"RobinS" <
[email protected]> a écrit dans le message de (e-mail address removed)...
| So say I had a class called Customer that had a protected property called
| PhoneNumber.
Which is very doubtful because then it would not be visible to other
classes.
| Then I had a class called CustomerList that was a List(Of Customer), I
| could see the phone number, right? Because each item in the list is a
| Customer?
No, this is not correct. List<Customer> has no inheritance relationship with
Customer, it is simply a list that happens to hold Customer instances.
| But if i had a class called Product that instantiated a Customer inside
it,
| I could not see the PhoneNumber.
This is correct, but I feel that you really don't quite understand what is
involved here.
There are four visibilities that are commonly used in class design: private,
protected, internal and public.
Private visibility means that a member of a class can only ever be accessed
from code within that class.
Protected visibility means that a member of a class so marked can only ever
be accessed from code within either that class or from the code within any
class that derives or inherits from that class.
Internal visibility means that a member of a class can be accessed by code
in any class that is included in the same assembly as the declaring class.
Public visibility means that a member of a class can be accessed by any code
in any class anywhere in any assembly or program.
class Order
{
class Line
{
...
internal Line()
{
...
}
}
private List<Line> lines;
public ReadOnlyCollection<Line> Lines
{
get { return new ReadOnlyCollection<Line>(lines) }
}
public OrderLine AddLine()
{
Line newLine = new Line();
lines.Add(newLine);
return newLine;
}
}
class Test
{
static void Main()
{
Order order = new Order();
Order.Line line = order.AddLine();
line. ......
}
}
In this simple example, I want to hold a list of OrderLines in an Order but,
I don't want any other code outside of the Order class to be able to modify
that list. To this end, I declare the list in a private field but add a
public property that returns, not the original list, but a readonly list
wrapper that allows outside code to look at and modify items in the list but
that prohibits modification of the list itself.
The Order.Line class is nested in the Order class, thus allowing us indicate
to users that Line was part of the concept of an Order. Note that the
constructor of Line needs to be marked in such a way that only the Order
class is allowed to create instances of the Line class.
The constructor of the Line class cannot be marked as private or even
protected because, even though the Line class is part of the Order class,
its members' visibilities are regarded as if those members were in a totally
separate class. Therefore, in order to allow the Line constructor to be
visible to the Order class, we have to mark it as internal, as this is the
only way to allow another class in the same assembly to instantiate the Line
class.
class HelperClass
{
public void DoSomething()
{
...
}
}
class BaseClass
{
private HelperClass helper = new HelperClass();
protected HelperClass Helper
{
get { return helper; }
}
}
class DerivedClass : BaseClass
{
public void UseHelper()
{
Helper.DoSomething();
}
}
This is a typical use of the protected visibility to hide "helper" behaviour
from all classes except the class being helped.
I think your confusion arises because the original example that you quoted
tries to call a protected member on an instance of a base class from within
a method of a derived class.
In the same way, as I would not able to see a protected constructor on the
Line class, even though it was inside the Order class, so I cannot see
protected members of *any* class, unless the accessing code is part of the
declaring class or its derivatives.
class BaseClass
{
protected int x;
}
class DerivedClass : BaseClass
{
void Test()
{
BaseClass b = new BaseClass();
b.x // not visible
BaseClass b = new DerivedClass();
((DerivedClass) b).x = 10; // visible
In this second example, because b is really an instance of DerivedClass held
in a BaseClass reference, it can then be cast to DerivedClass and then the
protected member x is accessible due to the fact that we are in the code of
the DerivedClass.
BaseClass b = new BaseClass();
b.x // not visible
This Test() method is part of DerivedClass and that allows it to see any
protected members of BaseClass, but only if those members are actually part
of an instance of DerivedClass. In this last example, b is not DerivedClass,
it is only BaseClass, therefore x is not visible to *any* code outside of
BaseClass.
Just because DerivedClass inherits from BaseClass, it doesn't mean that code
inside DerivedClass can see protected members of BaseClass. This is only
allowed if the protected member is in the *same instance* of DerivedClass.
Any better ? Or just more confusing ?
Do you understand the difference between a class and an object or instance
of that class ?
Joanna