oops concept query - c#

I have a question related 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.

Related

Polymorphism, using methods of child classes

I have an interface IRecordBuilder and an abstract class Query with a field protected IRecordBuilder recordBuilder and a method public abstract IList<IRecords> GetRecordsFromResults();.
In Query child classes constructors, I specify a recordBuilder concrete type depending on which child class I am in, for exemple :
recordBuilder = new RecordsPerMonthBuilder(); //RecordsPerMonthBuilder implements IRecordBuilder
I would like to use my recordBuilder field in the implementations of the abstract method above, but the properties in the implementations of IRecordBuilder remains unknown at compile time and i can't use them.
Besides transfering recordBuilder from mother class to each child classes and instantiate it there with the proper type, is there a way to make the polymorphism work here ?
Here are the explanations in code format :
public interface IRecordBuilder
{
IRecords BuildRecord();
}
public class RecordsPerMonthBuilder : IRecordBuilder
{
public IRecords BuildRecord()
{
if(Foo != null) return new FooRecord(Foo); // class FooRecord : IRecord
return null;
}
public string Foo {get; set;}
}
public abstract class Query
{
protected IRecordBuilder recordBuilder;
public abstract IList<IRecords> GetRecordsFromResults();
}
public sealed class ConcreteQuery: Query
{
public ConcreteQuery()
{
RecordBuilder = new RecordsPerMonthBuilder();
}
public override IList<IRecords> GetRecordsFromResults()
{
var recordsList = new List<IRecords>();
recordBuilder.foo = "foo"; // IRecordBuilder does not contain a definition for foo
recordsList.Add(RecordBuilder.BuildRecord());
return recordsList;
}
}
I see three possible solutions for this:
Option 1: In your child class, cast the builder to the concrete type (since the child class created it, it knows the concrete type). If you do that, you might want to make the recordBuilder field readonly and pass it to the base constructor to ensure at compile time that its type cannot be changed.
Option 2: In your child class, keep an additional "strongly typed" reference to the record builder. (In fact, why do you even need the "interface typed" reference at all?)
public sealed class ConcreteQuery: Query
{
private RecordsPerMonthBuilder myBuilder;
public ConcreteQuery()
{
myBuilder = new RecordsPerMonthBuilder();
RecordBuilder = myBuilder;
}
public override IList<IRecords> GetRecordsFromResults()
{
var recordsList = new List<IRecords>();
myBuilder.foo = "foo";
recordsList.Add(myBuilder.BuildRecord());
return recordsList;
}
}
Option 3: Make your base class generic:
public abstract class Query<TBuilder> where TBuilder : IRecordBuilder
{
protected TBuilder RecordBuilder;
public abstract IList<IRecords> GetRecordsFromResults();
}
public sealed class ConcreteQuery : Query<RecordsPerMonthBuilder>
{
...
}
One area of confusion is that your Query class depends explicitly on one implementation of IRecordBuilder, RecordsPerMonthBuilder. The interface IRecordBuilder doesn't have a Foo property, but Query depends on the Foo property. Query is hard-coded to only use RecordsPerMonthBuilder.
It's difficult to see the intent. One way to clear it up is to make sure that any interaction between Query and an implementation of IRecordBuilder is defined in IRecordBuilder. Query should depend on the interface and shouldn't call any properties or methods that aren't in that interface.
If only one implementation of IRecordBuilder requires a Foo, then that value shouldn't be coming from your Query class because Query doesn't know that IRecordBuilder needs a Foo. It shouldn't know what an implementation of IRecordBuilder needs, only what it does.
Here's a way to move it around. You'll see this pattern a lot.
public abstract class Query
{
protected IRecordBuilder RecordBuilder { get; private set; }
protected Query(IRecordBuilder recordBuilder)
{
RecordBuilder = recordBuilder;
}
public abstract IList<IRecords> GetRecordsFromResults();
}
Now it will never know what the implementation of IRecordBuilder is. That's good. It's now impossible for it to depend on anything that's not in the IRecordBuilder interface. Now Query depends on an abstraction, applying the Dependency Inversion principle.
What about RecordsPerMonthBuilder? It depends on a value, Foo. Will every implementation of IRecordBuilder need that? If so you could add it to the interface:
IRecords BuildRecord(string foo);
But if only one implementation needs that value then it shouldn't come from Query, because Query shouldn't know the difference between one IRecordBuilder and another. I can't answer that more specifically because I don't know what Foo is.
Another suggestion: If the inheritance between Query and ConcreteQuery gives you any grief, just don't use inheritance. Sometimes trying to use inheritance creates complications and doesn't give us any benefit in return.

Implement copy/deepcopy on multiple base classes

not sure if this maybe is a codeReview post but here we go:
My goal is to re-implement the way objects are copied within our application. We have multiple base classes:
CoreList<T> // for all list classes
BasicReference // for all reference classes
CoreObject // for all "normal" domain objects
All classes inherit from these base classes. Right now the copy method is implemented on the CoreObject class and will go through the object tree via reflection, looking at each property type and select the correct way to copy the type and finally returning always CoreObject.
There are some problems which I don't like about that approach, which is why I would like to change it:
After copying an domain object you always have to cast it "back" to the original type, for example: Animal = animal.Copy() as Animal;
All logic to copy each type is within the CoreObject class even though it should not know about other base classes.
So my first attempt was to introduce a interface:
public interface IObjectCopy<out T>
{
T Copy();
}
Which then should be implemented on all base classes. Then every class is responsible for the way it is copied. For example (pseudo code):
public class CoreObject : IObjectCopy<CoreObject>
{
public virtual GerCoreObject Copy()
{
foreach (var prop in properties)
{
if (prop.IsNoSimpleType)
{
(prop as IObjectCopy).Copy()
}
}
}
That solves the copy-responsibility problem, in addition inherited classes can take care of the copy logic themselves.
Unfortunately that does not solve the return type, I still have to cast it to the correct type. I did not think of a better solution to solve this. Any ideas?
This problem could be solved in OO using covariant return types. Unfortunately C# does not support covariant return types like Java and C++, requiring it to always break type safety.
Without breaking type safety (casting) in C# this is unfortunately not possible.
Here are two possible options:
//explicit interface implementation
public class Animal : CoreObject, IObjectCopy<Animal>
{
Animal IObjectCopy<Animal>.Copy()
{
return (Animal) base.Copy();
}
}
//does not require an explicit cast
IObjectCopy<Animal> animalCopy = myAnimal;
Animal copiedAnimal = animalCopy.Copy();
//second option: shadow the original method and cast inside the object
public class Animal : CoreObject, IObjectCopy<Animal>
{
public new Animal Copy()
{
return (Animal) base.Copy();
}
}
Animal copy = myAnimal.Copy();
Another option using bounded quantification:
public class CoreObject : IObjectCopy<CoreObject>
{
public CoreObject Copy()
{
return Copy<CoreObject>();
}
protected T Copy<T>()
where T : CoreObject, new()
{
T t = new T();
//implement copy logic:
return t;
}
}
public class Animal : CoreObject, IObjectCopy<Animal>
{
public new Animal Copy()
{
return Copy<Animal>();
}
}
If I understood it correctly, you need Curiously recurring template pattern
public class BaseClass<T> where T : BaseClass<T>
{
public virtual T Clone()
{
// Perform cloning with reflection.
return clone as T;
}
}
Then you just define your class as:
public class EndObject : BaseClass<EndObject>
{
}
EndObject e;
e.Clone() // Will return EndObject type

Generic base class with multiple children

I currently have a small object hierarchy that looks like this:
public class BaseClass {
// this class is empty and exists only so the others can extend it and share the
// same base type
}
public class ChildA : BaseClass {
public Subject<AssociatedClassA> Results;
}
public class ChildB : BaseClass {
public Subject<AssociatedClassB> Results;
}
In my design I would like to enforce that every class that extends from BaseClass should contain a Subject<SomeType> called Results. I'm wondering if there is a way that I can move Results into the base class or an interface such that I can supply the generic type for the Subject when constructing the base class. For example, it would be awesome if I could do something like this:
ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>();
Or even better since there should really only be one template parameter that matches with ChildA if when I constructed it that could be taken care of for me:
ChildA instance = new ChildA();
// Results is automatically set to Subject<AssociatedClassA>
I'm stuck trying to implement this now as if I try to move Results into the base class the Subject requires a template parameter which I can't necessarily supply. There could potentially be more than 2 derived classes and I don't like the idea that someone extending this system has to know to add Results manually to each child class.
Following the suggestions of the 2 answers below this solves my desire to move Results into the base class, however I've run into another issue in that I was hoping to be able to use BaseClass as a generic parameter to methods such that any of the derived classes could be used. For example:
public void ProcessBaseClass(BaseClass base) {
// base could be ChildA or ChildB here
}
This no longer works since BaseClass now requires a type argument. Is there any way that I can have the best of both worlds here or am I stuck due to my design choices?
If appropriate, you can make the parent generic:
public class BaseClass<T> {
public Subject<T> Results;
}
public class ChildA : BaseClass<AssociatedClassA> {
}
public class ChildB : BaseClass<AssociatedClassB> {
}
You can make the base class itself generic:
public class BaseClass<T> {
public T Results { get; protected set; }
}

Calling Known Property from Unknown Class

I have a BaseClass from which I have derived multiple other Classes using Inheritance.
Elsewhere I want to be able to retrieve Properties from anyone of these inherited classes even though the type of Class isn't known until Runtime.
For example lets say I have two classes derived from BaseClass
FirstClass : BaseClass
SecondClass : BaseClass
My BaseClass has a property called ID which is an int (amongst many others)
At runtime my app will receive 'either' a FirstClass object or a SecondClass object, but either way I need to retrieve the ID property.
public int MyMethod(object unknownClass)
{
int myID = unknownClass.ID;
return myID //...does not compile
}
public int MyMethod(object unknownClass)
{
BaseClass tryCasting = (BaseClass)unknownClass;
int myID = tryCasting.ID;
return myID //...does not compile either
}
I'm not sure what else to try.
How can I get a Property which I know exists without knowing the Object type first?
Don't use object and use BaseClass:
public int MyMethod(BaseClass unknownClass)
{
int myID = unknownClass.ID;
return myID;
}
See the answer from Darren Davies for your specific case of ID. The approaches in this answer are useful when the property is defined in the derived classes, not the base class.
Use dynamic instead of object. That will use the runtime to retrieve the actual object type.
public int MyMethod(dynamic unknownClass)
{
int myID = (int)unknownClass.ID;
return myID;
}
Alternatively, you can use Reflection to retrieve the property value:
var myID = (int)unknownClass.GetType().GetProperty("ID").GetValue(unknownClass);
Polymorfism is the answer. You should know that when you create a class derived from another, the derived class acquires inmediately the properties from the base class. Thus, if you don't redefine the method (override), when you call the method MyMethod on a derived class it will
always call the base method. So the next code should work well :
BaseClass {
private : int id ;
public : int getId { return id ; }
} ;
FirstClass : BaseClass { DO NOT OVERRIDE getID ...} ;
int main (void) {
BaseClass base ;
FirstClass first ;
base = first ;
base.getId() ; //Gets the id of first.
}
What does this program? When you assign first to base you upcast first type to BaseClass. Then when you get to the execution of base.getId() the program lookups if
there is a redefinition (overriding) of this method in FirstClass, if there isn't it calls the base method.
Hope that you find this information useful. You should read the first chapters of "Thinking in C++" of Bruce Eckels, it's a good introduction to Object Oriented Programming.

Why to assign an instance of a derived class to a variable which Type is not the one of the instance, but its base class

I've got 5 years experience. But to be honest while I know and use this construct...
Baseclass bc = new DerivedClass();
I have no idea what it actually does, not really, not truly. Is it a derived class or a base class? And I know that if I call bc.Method() I will get the derived class method. But only if I use the new keyword or override or something. To be honest I start to get a bit fuzzy here, I think I need to go back to basics with this, can anybody point me in the right direction?
You are creating an instance of DerivedClass and assigning it to a variable of type BaseClass. This can be useful if you have something like a base class Animal with two derived classes Fish and Dog, but you do not know which one will be instantiated and this is not important in your context because you are going to invoke a method which is defined in the base class. For instance you could have something like this:
Animal a;
if (whatever you want)
a = new Dog();
else
a = new Fish();
a.Feed();
Be careful with the use of modifiers, because if you define Feed in Animal with virtual and redefine it in Fish with override, the Fish version will be executed (it is linked at execution time). If you dont't mark the base version as virtual and mark the Fish version as new, the Animal version is executed (it is linked at compile time).
It creates an instance of DerivedClass and implicitly casts it to type Baseclass.
As I assume that this compiles it means that either DerivedClass inherits from Baseclass, e.g.:
class DerivedClass : Baseclass
{
}
Or there is an implicit cast operator for casting between these types, e.g.
class DerivedClass
{
public static implicit operator Baseclass(DerivedClass d)
{
// return a Baseclass here
}
}
Using the following
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Employee : Person
{
public string RoleName { get; set; }
}
If we create a new instance of Employee, but our variable declaration is in fact Person, all that will happen is an implicit cast to Person, meaning we won't have access to any of the methods or properties in Employee. I suppose this could be useful if the constructor of Employee affects the constructor of Person, but we don't care about anything in Employee, however I wouldn't recommend it. Instead I would recommend constructing a method that utilises clearer polymorphism. This is when a derived object is used as a parameter, when in fact the parameter type is that of one of its bases, for example.
public void DoSomething(Employee employee)
{
// here we do something with an employee
// ...
string fullName = GetTheirFullName(employee);
}
public string GetTheirFullName(Person person)
{
return (person.FirstName + " " + person.LastName).Trim();
}
It just create an instance of DerivedClass and assign it to bc which is of type BaseClass

Categories

Resources