I have scenario like below
public abstract class Test
{
public string name;
public abstract bool is_selected();
}
public class Campus : Test
{
}
Now Campus must and should implement is_selected() method otherwise it throws an error.
Adding to the same lines I want 'name' field also like that. I mean name field must be given a value.
How can I do that?
Any help greatly appreciated.
Thanks in advance :)
I can find two options
Use a parameterized constructor, so the derived class must provide a constructor which initialize the fields.
public abstract class Test
{
public string name;
protected Test(string name){ this.name = name; }
}
public class Campus : Test
{
public Campus() : base("Init the name here") {}
}
Use an abstract property, this is already metioned by other people.
public abstract class Test
{
public abstract string name { get; }
}
public class Campus : Test
{
public override string name => "name";
}
Related
public abstract class Beverage
{
public string description = "Unknown Beverage";
public string GetDescription()
{
return description;
}
}
public abstract class CondimentDecorator : Beverage
{
public abstract new string GetDescription();
}
public class Espresso : Beverage
{
public Espresso()
{
description = "Espresso";
}
class Mocha : CondimentDecorator
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string GetDescription()
{
return beverage.GetDescription() + ", Mocha";
}
Espresso is intended to be the component, and Mocha is intended to be the wrapper.
Now when I instantiate without using composition the code executes as expected and returns the description: Espresso:
static void Main(string[] args)
{
Beverage beverage = new Espresso();
Console.WriteLine(beverage.GetDescription());
Output: Espresso
However, when I use composition, the beverage description field from the Beverage base class is accessed and the program returns the description "Unknown Beverage." However, I'm expecting the output: "Espresso, Mocha"
Beverage beverage2 = new Espresso();
beverage2 = new Mocha(beverage2);
Console.WriteLine(beverage2.GetDescription());
It's because the GetDescription method in Beverage isn't virtual. When you write beverage.GetDescription(), the compiler looks and sees that the type of beverage is Beverage and then sees that it has a non-virtual GetDescription method. Since it's not virtual, the derived GetDescription isn't called.
What you want is something more like this:
public abstract class Beverage
{
public string description = "Unknown Beverage";
public virtual string GetDescription()
{
return description;
}
}
public abstract class CondimentDecorator : Beverage
{
public override string GetDescription()
{
return GetDescriptionOverride();
}
protected abstract string GetDescriptionOverride();
}
With the following line you are hiding the GetDescription method on the base class
public abstract new string GetDescription();
In the second example, where you see the problem, you are typing the variable as Beverage. Therefore you end up calling the method on the base class.
As a simple example:
public class First
{
public string GetName()
{
return "First";
}
}
public class Second : First
{
public new string GetName()
{
return "Second";
}
}
public static class Program
{
public static void Main(string[] args)
{
Second second = new Second();
Console.WriteLine(second.GetName());
// Prints "Second"
First first = second;
Console.WriteLine(first.GetName());
// Prints "First"
Console.ReadKey();
}
}
Then try the following change:
public class First
{
public virtual string GetName()
{
return "First";
}
}
public class Second : First
{
public override string GetName()
{
return "Second";
}
}
You will find it prints Second both times.
Whenever a class defines a virtual function (or method), most compilers add a hidden member variable to the class which points to an array of pointers to (virtual) functions called the virtual method table (VMT or Vtable). These pointers are used at runtime to invoke the appropriate function implementations, because at compile time it may not yet be known if the base function is to be called or a derived one implemented by a class that inherits from the base class.
Virtual method table
#kai pointed out the problem. The method need to be defined as virtual. Then the runtime knows to lookup an override method for runtime type which is Moccha in this case. Also if CondimentDecorator is abstract, there is no need to re-define CondimentDecorator again.
public abstract class Beverage
{
public string description = "Unknown Beverage";
public virtual string GetDescription()
{
return description;
}
}
public abstract class CondimentDecorator : Beverage
{
}
//no change to the rest
...
Do this and you will see output
"Espresso, Mocha"
I am currently in the middle of self-teaching some basic concepts of C# and I am experimenting with abstract classes and polymorphism. I thought I got the basic concept but it turned out that the concept doesn't work like I understood it :). However - I hope I get some answers which clear the dust a little bit :).
The whole task I am trying to achieve is to extend an abstract base class and use the extension with an object of the base class. Like here:
I have an abstract class which implements an abstract property like:
public abstract class BaseClass
{
public abstract MyProperty mP{get;}
}
where the property is
public abstract class MyProperty
{
public abstract string PropertyName{get;}
}
Now I am deriving the MyProperty class for an actual implementation like
public class DerivedProperty : MyProperty
{
public override string PropertyName
{
get
{
return this._name;
}
}
private _name = "Property1";
/* some other implementation follows here...... */
}
As I've understood polymorphism and inheritance it should now be possible to instantiate a derived class from BaseClass and override the property MyProperty with an object of DerivedProperty like this:
public class DerivedClass : BaseClass
{
public override DerivedProperty mP
{
get
{
return dP;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
Because DerivedProperty is an object of MyProperty and DerivedProperty at the same time it is possible to use it where either MyProperty or DerivedProperty is referenced. At least that's what I thought but it seems that this is wrong.
Now I am wondering - why is polymorphism so useful when something like above is not possible? Because even when I try something like this:
public class DerivedClass : BaseClass
{
public override MyProperty mP
{
get
{
return dP as DerivedProperty;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
I still get only my base object MyProperty and not my extended object DerivedProperty which I want to get.
I know why I get those results - I just don't seem logical to me :). Is it really like polymorphism is supposed to work or is my implementation just crap and I have to do it in a different way to get my extended property?
Appreciate your help here!
You have to provide the same type for overrided property. You can use it later in your abstract BaseClass. Parameters as well as return value of member have to be the same when overriding. It is usually not a problem.
I've prepared following examples that my code look similar to yours.
In some scenarios I've seen that there is added second property with more specific type and different (more specific) name:
public abstract class BaseCar
{
public abstract BaseDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override BaseDriver Driver { get { return _agressiveDriver; } }
public AgressiveDriver AgressiveDriver { get { return _agressiveDriver; } }
}
Second approach is to use generics:
public abstract class BaseCar<TDriver>
where TDriver : BaseDriver
{
public abstract TDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar<AgressiveDriver>
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override AgressiveDriver Driver { get { return _agressiveDriver; } }
}
but I think first approach is better because there is no problem with creating/using BaseCar objects (for example to create BaseCar<> variable you have to specify type parameter). Also it makes sense to create more specific name for more specific property.
I think you have an extra bit of complexity you don't need. You have an abstract class inside an abstract class. If you are just learning/relearning this you have skipped a couple easy steps for understanding. Here's a simpler example to start with.
public abstract class Shape
{
public abstract double GetArea();
public abstract double Circumference();
}
public class Square: Shape
{
public double width {get; set;}
public override double GetArea()
{
return width * width;
}
public override Circumference()
{
return width * 4;
}
}
You can now instantiate a Square or create a Circle Class and be able to use either where you use Shape.
I have many classes that have the following members/methods:
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public bool isNamed(String name) { return getName().Equals(name); }
Every time I create a new class that has a member "name", I have to rewrite all these.
Is there a way to write the methods one time and to make them apply to any class I want?
Your code can be converted to:
public String Name { get;set;}
Then you can use it as so:
nObject.Name = "Stefan";
if(nObject.Name == "Stefan"){
// do something
}else{
// do something else
}
To apply to all the classes automatically you can just make this into an interface:
public interface INameable{
public String Name {get;set;}
}
Doing this will allow you to inherit from other base classes of importance.
see here for an example
class YourClass : INameable{
//implementation
}
And now, YourClass has "Name" property automatically inserted.
You'd simply define a base class (you could make it abstract):
public abstract class Named
{
public string Name { get; set; }
}
and inherit from it:
public class Person : Named
{
}
You don't really need isNamed as in C#, it is perfectly safe to compare strings with ==.
If your class already inherits from another class which is not Named, you'll have to manually add the Name auto property or resort to simulated multiple inheritance.
Alternatively, you could create a specific modification of Named for every base class:
public abstract class NamedLifeForm : LifeForm
{
public string Name { get; set; }
}
public class Person : NamedLifeForm
{
// Person inherits both a Name and all relevant members of LifeForm
}
Another alternative would be to create a generic wrapper, Named<T>, that would have two properties: the Name and an instance of T. But that would make construction and access cumbersome, so I don't recommend it.
C# has AutoProperties just for that:
public String Name {get; set; }
This handles both the getName() and the setName() you talked about.
Usage:
To set a value: Name = "MyName;
To get a value: string theName = Name;
I'd suggest reading up on Object Oriented Programming. You can save yourself a lot of time and effort (and heckling). Here is a good primer http://www.amazon.com/Beginning-Object-Oriented-Programming-Dan-Clark/dp/1430235306
To answer your specific question, you should read about inheritance. It lets you define a "Parent" class with functions. Then you can inherit with "Child" classes and have those same functions.
http://msdn.microsoft.com/en-us/library/ms173149(v=vs.80).aspx
Here is a code example
public class PersonBase
{
private String name;
public String getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
public bool isNamed(string name)
{
return this.name.Equals(name);
}
}
public class Employee : PersonBase
{
}
Employee will now have whatever was defined by PersonBase.
As others have pointed out, you can simplify you code with properties. Also you should check for null values before using "this.name".
Here is a link to what properties are:
http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx
The simplified code example would be:
public class PersonBase
{
public String Name { get; set; }
}
public class Employee : PersonBase
{
}
I hope this helps get you pointed in the right direction for learning about these concepts.
I have a need where I have to add some new fields to an existing class along with all its existing fields/attributes.
So whenever my derived class is filled by DAL, I will be filling all fields of base class as well. Currently, I am doing it like this but not sure this is the right way ? Please give me an example. Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
public class Employee
{
private int _id;
private int _name;
public int ID
{
set { _id=value;}
get { return _id;}
}
public int Name
{
set { _name=value;}
get { return _name;}
}
protected void SetName ()
{
_name=value;
}
protected void SetID()
{
_id=value;
}
}
public class EmployeeWithDepartmentName:Employee
{
private string _deptName;
public string DeptName
{
set { _deptName=value; }
}
public setBaseEmpName()
{
base.SetName();
}
public setBaseID()
{
base.SetID();
}
}
Everything in a base class can automagically be accessed from derived classes without doiing anything, just use the property/method name directly.
public class MyBase
{
public string UserName {get;set;}
}
public class MyClass : MyBase
{
public void DoSomething()
{
Console.WriteLine("UserName: {0}", UserName);
UserName = "Anders";
}
}
You can also do this:
MyClass myClass = new MyClass();
myClass.UserName = "Rune";
Protected means that only derived classes can access the property/method. Public means that everyone can access the properties/methods.
Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
It's not two objects, it's one object created from two different classes (that's how inheritance works).
Read this article about inheritance: http://www.csharp-station.com/Tutorials/lesson08.aspx
Ok, I have the following structure. Basically a plugin architecture
// assembly 1 - Base Class which contains the contract
public class BaseEntity {
public string MyName() {
// figure out the name of the deriving class
// perhaps via reflection
}
}
// assembly 2 - contains plugins based on the Base Class
public class BlueEntity : BaseEntity {}
public class YellowEntity : BaseEntity {}
public class GreenEntity : BaseEntity {}
// main console app
List<BaseEntity> plugins = Factory.GetMePluginList();
foreach (BaseEntity be in plugins) {
Console.WriteLine(be.MyName);
}
I'd like the statement
be.MyName
to tell me whether the object is BlueEntity, YellowEntity or GreenEntity. The important thing is that the MyName property should be in the base class, because I don't want to reimplement the property in every plugin.
Is this possible in C#?
I think you can do it through GetType:
public class BaseEntity {
public string MyName() {
return this.GetType().Name
}
}
public class BaseEntity {
public string MyName() {
return this.GetType().Name;
}
}
"this" will point to the derived class, so if you were to do:
BaseEntity.MyName
"BaseEntity"
BlueEntitiy.MyName
"BlueEntity"
EDIT: Doh, Gorky beat me to it.
C# implemented a way to look at objects called Reflection. This can return information about the object you are using.
The GetType() function returns the name of the class you are calling it on. You can use it like this:
return MyObject.GetType().Name;
Reflection can do a lot of things. If there is more that you want to know about reflection you can read about it on these websites:
MSDN Reflection Article
Oreilly Chapter
Code Source Tutorial
Change your foreach statement to the following
foreach (BaseEntity be in plugins) {
Console.WriteLine(be.GetType().Name);
}
If you haven't overridden the ToString() method for the class, then you can just write the following
string s = ToString().Split(',')[0]; // to get fully qualified class name... or,
s = s.Substring(s.LastIndexOf(".")+1); // to get just the actual class name itself
using yr code:
// assembly 1 - Base Class which contains the contractpublic class BaseEntity
{
public virtual string MyName // I changed to a property
{
get { return MyFullyQualifiedName.Substring(
MyFullyQualifiedName.LastIndexOf(".")+1); }
}
public virtual string MyFullyQualifiedName // I changed to a property
{
get { return ToString().Split(',')[0]; }
}
}
// assembly 2 - contains plugins based on the Base Class
public class BlueEntity : BaseEntity {}
public class YellowEntity : BaseEntity {}
public class GreenEntity : BaseEntity {}
// main console app
List<BaseEntity> plugins = Factory.GetMePluginList();
foreach (BaseEntity be in plugins)
{ Console.WriteLine(be.MyName);}
Try this pattern
class BaseEntity {
private readonly m_name as string;
public Name { get { return m_name; } }
protected BaseEntity(name as string) {
m_name = name;
}
}
class BlueEntity : BaseEntity {
public BlueEntity() : base(typeof(BlueEntity).Name) {}
}