oops concept query
I have a question rela开发者_开发百科ted to OOPS concept.
I have a base class
public class BaseClass
{
public int i = 10;
public int x = 30;
public string str = "Hello";
public virtual string Hello()
{
return "Hello of base class called";
}
}
I have a child class
public class ChildClass : BaseClass
{
public int i = 20;
public int z = 90;
public override string Hello()
{
return "Hello of child class called";
}
}
Now i have seen that the below code works fine
BaseClass baseObject = new ChildClass();
and when I type baseObject. then i only see members of BaseClass
only.
First question: Can someone advise me on a situation where a developer needs to do this BaseClass baseObject = new ChildClass();
?
Second question: If my BaseClass
object has a reference to my child class object then why are my child member variables not accessible through this baseObject
?
To answer your first question.
Developers do this to provide abstraction over what actual object they are referring to, which provides flexibility and 'loose-coupling' over the code that uses it.
For example (common scenario - which i use a lot), you might have 10 child classes which extend the base class. What if you wanted a method to return each type of child class? Well, without this type of declaration you would need 10 methods. But if you specified the return type of "BaseClass", you could return all the 10 types of child classes from the one method. This technique ties in closely with the user of interfaces.
E.g
public BaseClass GetDynamicChildClass()
{
if (someCondition) return ChildClass();
else if (someOtherCondition) return SomeOtherChildClass();
}
To answer your second question.
You can't see the child properties because you have said "baseObject" is of type "BaseClass" - the compiler has typed the object to this. In order to access the child properties, you need to cast it as the child type:
BaseClass b = new ChildClass();
int x = b.z; // error.
int x = ((ChildClass)b).z; // works - this is a cast, throws exception in bad conversion
ChildClass c = b as ChildClass; // also works, different type of cast, returns null in bad conversion
int x2 = c.z;
This type of concept (polymorphism) is fundamental to Object-Orientated programming. Have a look at this excellent StackOverflow question: Try to describe polymorphism as easy as you can
It explains it in the simplest way possible, without tying it down to any particular programming framework, which in my opinion is the best way to learn OO.
Hope that helps.
When you want to have objects with individual behavior that have a set of common functions. For example you want to put objects of different types into a list.
The underlying type is still ChildClass but you are currently working on a BaseClass type. That is why you only see the members for BaseClass. It is though still possible to convert the BaseClass instance to a ChildClass instance with a cast operation or the 'as' keyword.
When you do
BaseClass baseObject= new ChildClass();
The static declared type of the object is that of "BaseClass
".
Hence you can only see the objects of "BaseClass"
type.
If you are sure that the object is of ChildClass Type, you can typecast baseObject to "ChildClass" and then use the ChildClass members
((ChildClass) baseObject).
- should help intellisense give you the members of the child class.
Using BaseClass baseObject= new ChildClass();
is the base for RunTime polymorphism.
It is very commonly used if you need the overridden child logic to be called but the interface is that of the base class
EDIT : Example of a scenario where you would use it
Class User
has derived classes called Employee
and 3rdPartyUser
Class User has a virtual method called GetRoleInformation - which is used to obtain Role Info for user from the companies Active directory.
However, for 3rd party user, as the information does not exist in AD, the logic for getting the Role Information involves calling a Web Service to retrieve the data. In this case, GetRoleInformation is overridden in 3rdPartyUser class
Now, in the program, on the Login Page, once authenticated, i either get back an object of Employee or 3rdPartyUser.
I pass this object to a method with a signature RoleCollection GetRole( User loggedInUser)
Inside this method, without having to determine the type of the user, i just call loggedInUser.GetRoleInformation
and depending on whether it is Employee / 3rdPartyUser
, the appropriate base / overridden method will be called and Role data will be retrieved from either AD / Web Service.
Long story short :
Advantage of
BaseClass baseObject= new ChildClass();
OVER
ChildClass baseObject= new ChildClass();
is in scenarios when you are not sure of the exact type of child object that is going to be assigned to baseObject variable eg: in this case Employee / 3rdPartyUser Eg:
BaseClass baseObject= GetLoggedInUser();
where signature of this method is User GetLoggedInUser(string userid)
Otherwise, in an example like yours, where the object is ALWAYS of type "ChildClass", i beleive that there is no advantage to doing it.
The answer of your first questiom : this type of implementation is common when we are using abstract factory patten for the i wll give u a simple example which is creates a family ford car ..
public class AbstractFactoryExample
{
public AbstractFactoryExample()
{
string type = "";
CarFactory facotry=null;
if (type == "FORD")
{
facotry = new FordCarFactory();
}
ICar MyFamilyCar = facotry.CreateFamilyCar();
ICar MyCityCar = facotry.CreateCityCar();
}
}
public interface ICar
{
}
public abstract class CarFactory
{
public abstract ICar CreateFamilyCar();
public abstract ICar CreateCityCar();
}
public class FordCarFactory : CarFactory
{
public override ICar CreateFamilyCar()
{
return new FordFamilyCar();
}
public override ICar CreateCityCar()
{
return new FordCityCar();
}
}
public class FordFamilyCar : ICar
{
}
public class FordCityCar : ICar
{
}
to your second question :
you are declaring the object as baseclass so it shows only the methods in it only and if you sure about the the generated instance is of type child class
((ChildClass) baseObject)
can solve the problem
please excuse me for my bad english
Here is an example where the only method we care about is in the base class. By using this type of abstraction we can easily add more report types.
public class Report
{
public virtual string ContentType
{
get { return "application/octet-stream"; }
}
public virtual byte[] Build()
{
return new byte[0];
}
public static Report Create(ReportType type)
{
switch (type)
{
case ReportType.Pdf:
return new PdfReport();
case ReportType.Html:
return new HtmlReport();
case ReportType.Doc:
return new DocReport();
case ReportType.Xls:
return new XlsReport();
default:
return new DefaultReport();
}
}
}
Then from the client side we only have to do this:
ReportType type = GetReportTypeFromFormPost();
Report report = Report.Create(type);
// ...
Response.Write(report.Build());
In fact it makes more sense to you, when you use Factory Pattern (http://gsraj.tripod.com/design/creational/factory/factory.html) to instantiate the object. This would abstract out the implementation specific details to different class.
精彩评论