Difference between abstract class constructor and normal class constructor? - c#

abstract class Animal
{
public string DefaultMessage { get; set; }
public Animal()
{
Console.WriteLine("Animal Cstor called");
DefaultMessage = "Default Speak";
}
public virtual void Speak()
{
Console.WriteLine(DefaultMessage);
}
}
class Dog : Animal
{
public Dog()
: base()//base() redundant. There's an implicit call to base here.
{
Console.WriteLine("Dog cstror called");
}
public override void Speak()
{
Console.WriteLine("Custom Speak");//append new behavior
base.Speak();//Re-use base behavior too
}
}
or else
class Animal
{
public string DefaultMessage { get; set; }
public Animal()
{
Console.WriteLine("Animal Cstor called");
DefaultMessage = "Default Speak";
}
public virtual void Speak()
{
Console.WriteLine(DefaultMessage);
}
}
class Dog : Animal
{
public Dog()
: base()//base() redundant. There's an implicit call to base here.
{
Console.WriteLine("Dog cstror called");
}
public override void Speak()
{
Console.WriteLine("Custom Speak");//append new behavior
base.Speak();//Re-use base behavior too
}
}
what is the Difference between abstract class constructor and normal class constructor?

No difference rather than an abstract class constructor can't be called publicly because otherwise it would defeat the purpose of abstract classes (i.e. they must be inherited and cannot be instantiated directly, thus an abstract class public constructor can be only called by a derived class constructor!).

Whilst you cannot instantiate an abstract class it may have a constructor that is called from a derived one. Thus an abstract one should never be public but protected. So the only difference from an API-point of view is that the first cannot be called directly from any arbitrary class while a normal constrcutor can be called allways from everywhere (depending on access-modifier of course).
To be more precise: an Animal-class should probably NEVER be not-abstract. That would mean that there are animals existing that cannot be categorized any further to Cats, Dogs or whatever, but only animals.

Related

Passing inherited class

I'm trying some simple code to understand the generics in C#. The purpose of the code here is to have a trainer that has her own animal and will ask it to do various stuff (for the sake of the example, to jump).
The problem is with the constructor of the trainer. I would like to be able to pass a Dog, or a Cat. They both inherit from the same class, but because I specified the type definition it seems I can't pass them as argument, they can't be both valid. Is there a way to specify a generic class like "Animal" so I could pass a dog or a cat and keep it as a member?
class AnimalDefinition
{
public Fur Fur;
}
class DogDefinition : AnimalDefinition
{
public BarkSound Bark;
}
class CatDefinition : AnimalDefinition
{
public MeowSound Meow;
}
class Animal<TDefinition> where TDefinition : AnimalDefinition
{
public TDefinition Definition;
public void Jump()
{
Console.WriteLine("Jump.");
}
}
class Dog : Animal<DogDefinition>
{
public Dog(DogDefinition def)
{
Definition = def;
}
}
class Cat : Animal<CatDefinition>
{
public Cat(CatDefinition def)
{
Definition = def;
}
}
class Trainer
{
Animal _animal;
public Trainer(Animal myAnimal)
{
_animal = myAnimal;
}
public MakeJump()
{
_animal.Jump();
}
public Listen()
{
// if T is DogDefinition hear barking
// else if T is CatDefinition hear a meowing, etc
}
}
EDIT: Additional question following Chris Berger's answer (which works, but I didn't change the code to keep the question/answer logical). I added a definition member in the Animal class. Is there any way I can access Bark or Meow from inside the Trainer class or will I have to derivate the class Trainer with CatTrainer : Trainer<CatDefinition>? That is, is there something similar to what we have with classes,
if(T is CatDefinition)
{ // Meowing}
else
{}
I think I agree with the first commenter, that you don't necessarily want generics for this, but assuming you have some other reason for wanting generics...
The solution here is to create a class Animal, which Animal<T> derives from.
For example:
public class Animal
{
public virtual void Jump()
{
Console.WriteLine("Jump.");
}
}
public class Animal<T> : Animal where T : AnimalDefinition
{
public override void Jump()
{
//you can override Jump here if you want to
}
}
public class Dog : Animal<DogDefinition> {}
public class Cat : Animal<CatDefinition> {}
Or, actually, a second option is to give Trainer visibility to the generic parameter:
public class Animal<T> where T : AnimalDefinition
{
public void Jump()
{
Console.WriteLine("Jump.");
}
}
public class Dog : Animal<DogDefinition> {}
public class Cat : Animal<CatDefinition> {}
public class Trainer<T> where T : AnimalDefinition
{
Animal<T> _animal;
public Trainer(Animal<T> myAnimal)
{
_animal = myAnimal;
}
public MakeJump()
{
_animal.Jump();
}
}
And as a tangent... this might be a good place to use a self-referential generic.
public class Animal<T> where T : Animal<T> { }
public class Dog : Animal<Dog> { }
Here's a little more reading on that pattern: https://blogs.msdn.microsoft.com/simonince/2008/06/12/generics-the-self-referencing-generics-pattern/

How do you make members inaccessible to sub-derived classes?

Say I have a base class like this:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
//...
}
}
Then I inherit this class in a separate assembly:
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
MyMethod(MyConstantString);
}
}
I now want to make sure that any other class that inherits from MyDerivedClass does not have access to the MyBaseClass.MyMethod() method. (To clarify, I still want to be able to call MyDerivedClass.MyMethod() with no parameters)
I tried using protected internal but that didn't work.
Update: I'm trying to do this because the application I'm working on has a bunch of separate programs that use a base class. There are 5 different "types" of programs, each performs a specific, separate function but they all have some common code that I am trying to abstract into this base class. The common code is 99% the same, differing only slightly depending on what type of program is calling it. This is why I have my base class taking a string parameter in the example which then disappears in the derived base class, as that class knows it performs role x so it tells its base class accordingly.
Then I would instead of inheritance use composition in the MyDerivedClass. So all derived classes from this class does not know the methods from MyBaseClass. The class MyBaseClass would i make package visible so it is not possible to use it.
abstract class MyBaseClass
{
void MyMethod(string myVariable)
{
//...
}
}
abstract class MyDerivedClass
{
static readonly string MyConstantString = "Hello";
private MyBaseClass baseClass;
MyDerivedClass(MyBaseClass baseClass)
{
this.baseClass = baseClass;
}
protected void MyMethod()
{
baseClass.MyMethod(MyConstantString);
}
}
The class names should be changed of course.
This is not quite possible. And it may be a sign that your object design might be in trouble, but that's not a question for SO.
You can try a bit more underhanded approach, though:
public abstract class MyBaseClass
{
protected abstract string MyConstantString { get; }
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected override sealed string MyConstantString => "Hello";
}
Or, more typically, just use the constructor to pass the required argument:
public abstract class MyBaseClass
{
private readonly string myString;
protected MyBaseClass(string myString)
{
this.myString = myString;
}
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected MyBaseClass() : base("Hello") {}
}
Classes derived from MyDerivedClass have no way to change the argument in either case, the second approach is a bit nicer from inheritance perspective (basically, the type is a closure over an argument of its ancestor type).
You cannot stop inheriting classes from calling this method - you have made it protected so your intent is for it to be accessible to classes that inherit from it, whether directly, or via another sub-class.
If you want to keep the inheritance, the best you can do is to throw an error if the sub-class calls it in MyDerivedClass:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
Console.WriteLine(myVariable);
}
}
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
base.MyMethod(MyConstantString);
}
protected new void MyMethod(string myVariable)
{
throw new Exception("Not allowed");
}
}
public class SubDerivedClass : MyDerivedClass
{
static readonly string MyConstantString = "Hello";
public void Foo()
{
MyMethod(MyConstantString);
}
}
When Foo() is called in SubDerivedClass, it will call MyMethod in DerivedClass, which will throw the Exception.

C# and inheritance chain of multiple types using generics

I have this setup, and it didn't work as I expected. It seems to me that a generic T in a base class is not the same as the generic T in its sub-class.
namespace StackOverflowQuestion
{
public class Poco1
{
public string Data { get; set; }
}
public class Poco2 : Poco1
{
public string ExtraData { get; set; }
}
public class Poco3 : Poco2
{
public string EvenMoreData { get; set; }
}
public class Base<T> where T: Poco1
{
public virtual void Method(T parameter)
{
// Do something even more general with Data...
parameter.Data = "Test";
}
}
public class FirstLevel<T> : Base<Poco2> where T:Poco2
{
public override void Method(Poco2 parameter)
{
// Do something general with ExtraData...
base.Method(parameter);
}
}
public class SecondLevel<T> : FirstLevel<Poco3> where T: Poco3
{
public override void Method(Poco2 parameter) // <-- Why not Poco3?
{
// Do something with EvenMoreData...
base.Method(parameter);
}
}
}
What I actually expected was that the Method override in type SecondLevel<T> should say Poco3 and not Poco2. Especially as I put a constraint on T to be of type Poco3.
Is it possible to achieve this in another way? It seems to me that the generic T can't be "overridden" the way I wanted. I suspect T in Base<T> is not the same as T in FirstLevel<T> and that T in FirstLevel<T> is not the same as T in SecondLevel<T>?
If SecondLevel<T> inherits from Base<T> then I get Poco3 in the Method override, but not when I inherit from FirstLevel<T>.
I can live with this issue, but then I need to cast the poco parameter type in Level-type sub-classes (from level 2 and up). In my opinion, that should be unnecessary as long as I specify the constraint. But, of course, there might be a good reason for this behavior that I don't see at the moment.
Rather than specifying the POCO type in each overridden method signature you can instead use the T type parameter.
T is already constrained to the POCO type you want so it should behave exactly as you want.
Oh, and I'd do the same with the type you're passing to the base class as well.
e.g.
public class FirstLevel<T> : Base<T> where T:Poco2
{
public override void Method(T parameter)
{
// Do something general with ExtraData...
base.Method(parameter);
}
}
public class SecondLevel<T> : FirstLevel<T> where T: Poco3
{
public override void Method(T parameter)
{
// Do something with EvenMoreData...
base.Method(parameter);
}
}

Why doesn't this method invocation invoke the derived class?

I have an interface IDeepCloneable, that I'm using to implement generic deep copying. I have a base class and a derived class as well, each implementing IDeepCloneable. I'm running into issues with derived classes.
Here is the code:
public class Program
{
public static void Main()
{
var a = new BaseClass();
var ac = a.DeepClone();
var b = (BaseClass)(new DerivedClass());
var bc = b.DeepClone();
}
}
public interface IDeepCloneable<T>
{
T DeepClone();
}
public class BaseClass : IDeepCloneable<BaseClass>
{
public string Value { get; set; }
public BaseClass(){}
public BaseClass(BaseClass copy)
{
Value = copy.Value;
}
public BaseClass DeepClone()
{
Console.WriteLine("BLAH1");
return new BaseClass(this);
}
}
public class DerivedClass : BaseClass, IDeepCloneable<DerivedClass>
{
public string SomeOtherValue { get; set; }
public DerivedClass(){}
public DerivedClass(DerivedClass copy)
: base(copy)
{
SomeOtherValue = copy.SomeOtherValue;
}
public new DerivedClass DeepClone()
{
Console.WriteLine("BLAH2");
return new DerivedClass(this);
}
}
This outputs:
BLAH1
BLAH1
I understand why it outputs BLAH1 twice, I'm just not sure how to fix it..
Your derived class needs to override the DeepClone() method, and your DeepClone method in the base class needs to be virtual.
Right now, your DeepClone method in the derived class is unrelated (other than having the same name) to the base class. See Interface Implementation Inheritance in the C# standard.
That said, it looks like you're trying to do deep copies. Have you considered using a BinaryFormatter to serialize and de-serialize your data?
since that base class or yours implements the interface already, so you can either make the base class's DeepClone method as virtual and override it, or you can do
public abstract class BaseClass : IDeepCloneable<T>
...
public abstract T DeepClone(){}
and in your DerivedClass do
public class DerivedClass : BaseClass<DerivedClass>

Can you override one of the abstract methods in a base class with another base class?

I have a base class that has some abstract methods on it and there are 21 classes that are inheriting from this base class. Now for one of those abstract methods I want to implement it with a common implementation for 6 of the 21 classes so I thought about creating another base class that would do this.
I am open to suggestions but my main purpose of creating another base class between the current base class and the 21 classes is to keep from repeating the same code in 6 of the 21 classes if I didn't have to.
Here is a sample of code to illustrate the situation:
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public virtual string OtherMethod()
{
return this.SomeMethod();
}
}
public abstract class AnotherBase : FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public override OtherMethod()
{
//this is the common method used by 6 of the classes
return "special string for the 6 classes";
}
}
public class Foo1 : FooBase
{
public override string Bar()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
public override string SomeMethod()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
}
public class Another2 : AnotherBase
{
public override string Bar()
{
//do something specific for the Another2 class here
return "Another special string";
}
public override string SomeMethod()
{
//do something specific for the Another2 class here
return "Another2 special string";
}
}
Yes, you can derive an abstract class from another abstract class
public abstract class FooBase
{
//Base class content
}
public abstract class AnotherBase : FooBase
{
//it is "optional" to make the definition of the abstract methods of the Parent class in here
}
When we say it is optional to define the abstract methods of the parent class inside of the child class, it is mandatory that the child class should be abstract.
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public abstract string OtherMethod();
}
public abstract class AnotherBase : FooBase
{
public override string OtherMethod()
{
//common method that you wanted to use for 6 of your classes
return "special string for the 6 classes";
}
}
//child class that inherits FooBase where none of the method is defined
public class Foo1 : FooBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
public override string OtherMethod()
{
//definition
}
}
//child class that inherits AnotheBase that defines OtherMethod
public class Another2 : AnotherBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
}
So I'm guessing that there will be 5 more classes like Another2 which inherits from AnotherBase that will have a common definition for OtherMethod
Yes, that is entirely possible and frequently done. There is no rule that says that you can have only one base class at the bottommost level of your class hierarchy; subclasses of that class can just as well be abstract and thereby become (somewhat more specialized) base classes for one group of classes indirectly derived from your general base class.
You should specify what exactly those classes do, but.. given the information you provided:
This is the exact problem that the Strategy pattern aims to solve, as shown in the example given in the Head First Design Patterns book.
You have an abstract Duck class, from which other ducks (e.g., RedheadDuck, MallardDuck) derive. The Duck class has a Quack method, that simply displays the string "quack" on the screen.
Now you are told to add a RubberDuck. This guy doesn't quack! So what do you do? Make Quack abstract and let the subclasses decide how to implement this? No, that'll lead to duplicated code.
Instead, you define an IQuackBehaviour interface with a Quack method. From there, you derive two classes, QuackBehaviour and SqueakBehaviour.
public class SqueakBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("squeak");
}
}
public class QuackBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("quack");
}
}
Now, you compose your ducks with this behaviour as appropriate:
public class MallardDuck : Duck
{
private IQuackBehaviour quackBehaviour = new QuackBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
public class RubberDuck : Duck
{
private IQuackBehaviour quackBehaviour = new SqueakBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
You can even inject an instance of IQuackBehaviour through a property if you want the ducks to change their behaviour at runtime.

Categories