سلام.
من مثلاً این رو دارم:
ok؟کد:namespace x
{
class a
{
// ...
}
public class b : a
{
// ...
}
}
حالا این ارور میده.
کلاس a رو چجوری تعریف کنم که کلاس b بتونه اون رو به ارث ببره ولی بیرون از این namespace کسی نتونه به ارث ببرش؟
Printable View
سلام.
من مثلاً این رو دارم:
ok؟کد:namespace x
{
class a
{
// ...
}
public class b : a
{
// ...
}
}
حالا این ارور میده.
کلاس a رو چجوری تعریف کنم که کلاس b بتونه اون رو به ارث ببره ولی بیرون از این namespace کسی نتونه به ارث ببرش؟
سلام.
یکی دیگه!
این رو ببینید:
کد:namespace x
{
class a
{
void c()
{
}
void d()
{
b.e();
}
}
class b
{
void e()
{
a.c();
}
}
}
می خوام هر کسی بتونه کلاس a من رو به ارث ببره ولی نتونه کلاس b رو به ارث ببره.
c باید قابلیت override شدن داشته باشه ولی d نه.
وقتی که طرف d رو از کلاس a صدا می زنه، همونطور که مشخصه باید e از کلاس b صدا زده بشه و (یه سری کار روش انجام بده و) اون هم c رو از کلاس a صدا بزنه.
هر کس این رو بنویسه جایزه داره.
راستیتش می خوام یه dll درست کنم که ملت بتونن از یه سری از متد ها و کلاس هاش استفاده کنند (با به ارث بردنش) در حالی که بقیه شون کاملاً داخلی باشن و طرف از وجودشون مطلع نشه.
---
نیما جان اگر دیدی و بلدی، بگو!
[این یه دفعه رو بپیچون بازی در نیار :دی]
این به خاطر این هست که کلاس b که از a ارث برده، بیشتر از پدرش دسترسی دارن بهش. یعنی پدرش به خاطر این که هیچ modifier ی نذاشتین براش، به صورت private در نظر گرفته میشه اما b چون public هست، بیشتر از a دسترسی بهش وجود داره. حالا اگه شما می خواین که از ش نشه بیرون از این namespace ارث بری بشه می تونین از دسترسیinternal براش استفاده کنین اما باز هم نمی تونین b رو public تعریف کنین. b هم باید internal، Protected یا private باشه.نقل قول:
خوب یکی یکی از اول:نقل قول:
کلاس a رو باید public تعریف کنین و کلاس b رو به صورت sealed
دومی:
متد c رو باید virtual تعریف کنین و متد d رو به صورت sealed
سومی:
این حالت که شما نوشتین برای فراخوانی متدهای غیراستاتیک که نمیشه! یعنی اگه بخواین یه متد رو با اسم کلاس صدا کنین حتما باید اون متد توی کلاس به صورت static تعریف بشه. اگه نخواین static باشن، باید یه نوع از کلاس مثلا a رو new کنین و بعد متدهایی که میخواین دسترسی بهشون داشته باشین رو public تعریف کنین.
سوال آخر هم که جایزه داره:31::
روی solution راست کلیک کنین و برین به properties ش. توی همون قسمت اول که application هست نوشته output type . از اونجا class library رو انتخاب کنین به جای windows application یا console application . همین : دی
موفق باشین:46:
سلام
ضمن تایید توضیحات کاربر MEHDI لازم دیدم در جهت کمک بیشتر، کمی توضیح و کدهای مربوطه را هم قرار دهم.
حتماً میدانید که در دات نت چهار عبارت مشخص کننده محدوده دید داریم:
پیشنهاد میکنم در اول تعریف هر چیزی (class, struc, enum, delegate ... field, property, method ...) صراحتاً حوزه دید را با کلمات کلیدی فوق مشخص کنید.کد://C#.Net
private
protected
internal
protected internal
public
'VB.Net
Private
Protected
Friend
Protected Friend
Public
در خصوص کلمات کلیدی وراثتی هم اینها را در اختیار دارید:
طبیعتاً همه سوالات شما با تلفیقی از کلمات کلیدی فوق قابل حل است.کد://C#.Net
sealed
virtual
abstract
override
:
'VB.Net
NotInheritable
MustInherit
Inherits
Implements
NotOverridable
Overridable
MustOverride
Overrides
==============
برای namespace نمیتوانید کاری کنید ولی برای داخل و خارج یک اسمبلی (dll یا exe) میتوان کارهایی کرد.نقل قول:
کلاس a رو چجوری تعریف کنم که کلاس b بتونه اون رو به ارث ببره ولی بیرون از این namespace کسی نتونه به ارث ببرش؟
اگر بخواهید کلاسهای CA و CB در دسترس عموم و public کنید،
تنها راهی که میماند آن است که سازنده های کلاس CA شما internal باشند.
حالا ...کد:namespace x
{
public class CA
{
internal CA()
{
}
// ...
}
public class CB : CA
{
// ...
}
public sealed class CC : CA {}
}
1- کلاس CA عمومی است.
2- کلاس CA در خارج از اسمبلی جاری راحت قابل نمونه سازی (new) نخواهد بود.
(اگر میخواهید به راحتی قابل new باشد، میتواند کلاس با کد خالی CC را اضافه کنید، تا در خارج از اسمبلی جاری CC را new کنند، که طبیعتاً فرقی با new کردن CA ندارد!)
3- کلاس CA قابل وراثت گیری نخواهد بود. (همان چیزی که خواسته اید)
4- کلاس CA میتواند abstract باشد که در این صورت در داخل اسمبلی هم قابل نمونه سازی نخواهد بود.
(پیشنهاد میکنم یکم کدها را اصلاح کنید و اجازه وراثت را بدهید! کی به کی؟!)
همانطور که کاربر MEHDI توضیح دادند:نقل قول:
می خوام هر کسی بتونه کلاس a من رو به ارث ببره ولی نتونه کلاس b رو به ارث ببره.
c باید قابلیت override شدن داشته باشه ولی d نه.
==============کد:namespace x
{
public class CA
{
public virtual void c()
{
//...
}
public void d()
{
//...
}
}
public sealed class CB
{
//...
}
}
به نظر میرسد دو کلاس a و b جدید شما با هم رابطه ی وراثتی ندارند، نتیجتاً یا باید متدها static باشند (روشی نچندان شی گرا) و یا اینکه یکی از کلاسهای a و b که زودتر نمونه سازی میشود دیگری را هم نمونه سازی کند.نقل قول:
وقتی که طرف d رو از کلاس a صدا می زنه، همونطور که مشخصه باید e از کلاس b صدا زده بشه و (یه سری کار روش انجام بده و) اون هم c رو از کلاس a صدا بزنه.
سعی کنید تفکر ساده و قدرتمندی داشته باشید.کد:namespace x
{
public class CA
{
private CB m_b;
public CA()
{
this.m_b = new CB(this);
}
public CA(CB value)
{
this.m_b = value;
}
public virtual void c()
{
//...
}
public void d()
{
//...
this.m_b.e();
//...
}
}
public class CB
{
private CA m_a;
public CB()
{
this.m_a = new CA(this);
}
public CB(CA value)
{
this.m_a = value;
}
public void e()
{
//...
this.m_a.c();
//...
}
}
}
موفق باشید.
هم با تشکر از جناب M E H D I و همچنین با تشکر ویژه از جناب استاد _H2_.
جدی عالی یاد می دید ها.
فقط میشه لطف کنید بگید کلید واژه ها بین #C و VB.net هم معنی هستند.
مثلاً NotInheritable خب خیلی معلومه ولی sealed چیز خاصی رو نمی رسونه! (+ اگر من رو بکشید با VB نمی نویسم و به جاش #Cش رو هر چند سخت، یاد می گیرم [و می دونم که این اصلاً خوب نیست و باید net. یاد گرفت نه #C])
sealed فقط به معنی NotInheritable نیست. sealed اگه برای کلاس باشه به معنی این هست که کلاس رو نمیشه ارث بری کرد اما اگه برای متد یا property استفاده بشه به این معنی هست که override فعلی آخرین override از متد هست یعنی دیگه نمیشه این متد رو override کرد. توی این حالت حتما باید به همراه کلمه کلیدی override استفاده بشه. برای struct ها هم نمیشه از sealed استفاده کرد چون به صورت ضمنی همه ساختارها sealed هستن که VB برای این حالت NotOverridable رو استفاده میکنه.نقل قول:
من VB رو زیاد کار نکردم باهاش. MustInherit فکر کنم میشه همون abstract
MustOverride هم فکر کنم همون abstract باشه وقتی روی متد استفاده بشه. Shadows هم فکر کنم یه چیزی تو مایه های new باشه برای متد ( درسته؟ :31: )
سلام
توضیحات کاربر MEHDI صحیح بودند و گفتم یک توضیح مختصر اضافه کنم ...
کلمات وراثتی VB.Net برای class و property+method تفاوت دارد ولی در C#.Net چنین نیست.
(البته در موارد دیگر چیزهای برعکس هم داریم که #C چند کلمه دارد و VB یک کلمه)
... این کلمات کلیدی C#.Net در واقع از ++C آماده اند.
البته کلمات کلیدی Shadows و Overloads و new (نه آن new نمونه سازی !) هم وجود دارند که خیلی به مفاهیم فوق نزدیک هستند ولی من نمیتوانم آنها را جزء گروه کلمات کلیدی مرتبط با وراثت و پلیمورفیزم طبقه بندی کنم.کد://C#.Net
sealed عدم بازتعریف برای کلاس و متد
virtual اجازه بازتعریف برای متدها
abstract اجبار در وراثت یا بازتعریف برای کلاس یا متد
override مشخص کنند بازتعریف برای متدها
: وراثت یا شمول یک واسط
'VB.Net
NotInheritable عدم وراثت کلاس
MustInherit اجبار وراثت کلاس
Inherits مشخص کننده کلاس پایه در وراثت
Implements مشخص کننده شمول یک واسط
NotOverridable عدم بازتعریف متد
Overridable اجازه بازتعریف متد
MustOverride اجباز بازتعریف متد
Overrides مشخص کنند بازتعریف برای متدها
==============
به بیان دیگر
sealed = NotInheritable, NotOverridable
virtual = Overridable
abstract = MustInherit, MustOverride
override = Overrides
: = Inherits, Implements
جمیعاً موفق باشید.