C# Abstract Method Inheritance and Hiding Methods Unintentionally - c#

I've got a question about accidentally hiding abstract methods.
I'm creating a basic Entity class as an interface from which to create all other entities in the game I'm working on.
From this Entity class, I have created several derived classes. There are things like MovingEntity, Trigger, Door, etc... Many of these children classes also have children derived from them. For example, MovingEntity has classes like Projectile and EnemyUnit as children.
In my base Entity class, I have methods like Update() and Render() that are abstract, because I want every entity to implement these methods.
Once I get down to the second level, however, -that's- where I hit my question/problem. I'll use the Trigger class, for example. Trigger derives from the base Entity class, but Trigger still has its own children (like TriggerRespawning and TriggerLimitedLifetime). I don't want to instantiate a Trigger object, so I can keep that class abstract - I will only create objects from Trigger's children classes. But what do I do with the abstract methods that Trigger is supposed to implement from Entity?
I thought I could just basically use the same code in Trigger as I did in Entity. Declare the same method, same name, same parameters, and just call it abstract. Then, Trigger's children would be forced to implement the actual functions.
This didn't work, however, because in the Trigger class, my build errors say that I am hiding the abstract methods from the base Entity class.
How can I pass down the idea of forcing the eventual children to implement these abstract methods without making all of the parents in-between implement them? Do I need to use virtual on the first round of children classes?
I haven't been able to find a good answer on this so far, so I decided to break down and ask. Thanks in advance, guys.

Just don't redeclare the methods at all - the eventual concrete classes will have to implement all the abstract methods still unimplemented all the way up the tree:
public abstract class Foo
{
public abstract int M();
}
public abstract class Bar : Foo
{
// Concrete methods can call M() in here
}
public class Baz : Bar
{
public override int M() { return 0; }
}

Related

Abstract class grandchildren inheritance

I'm trying to create a (rather clumsy) little game and I've come to a problem.
I have a class tree as follows:
Entity
Character
Player
Enemy
Static
Stairs
OtherEncounter
Now I intend to implement a generator which should generate a map based on some simple heuristics and via Entity constructor add encounters to some Tiles. For that I chose to use "Entity e" parameter in my Tile contructor.
Now for getting the correct type I set up a virtual method in all classes to return their exact type. That being abstract both in Entity.cs and Character.cs. But as expected, it doesn't do much good to inherit an abstract method and make it abstract again.
Thus, my question is, is there any kind of "correct" implementation or is there just some simple workaround? I could always just skip the method in Entity.cs and create two distinct in both Character.cs and Static.cs, but that just seems too... redneck-y.
TL;DR: How to inherit abstract method in grandchildren while not declaring in children.
Assuming Character is abstract, you don't have to implement it in Character at all. See this example:
public abstract class Parent
{
public abstract string Name {get;}
}
public abstract class Child : Parent
{
}
public class Grandchild: Child
{
public override string Name { get { return "Test"; } }
}
Because Child is also abstract, you don't need to redeclare any methods as abstract, so it just passes the implementation requirement onto Grandchild.
Try it online

Abstract Method in Non Abstract Class

I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.

Is an interface and an abstract class with just virtual abstract methods the same thing?

If I have a project that contains similar classes and some may use the same implementation, but in most cases they implement their own way of handling the methods defined in an interface or abstract class. I am trying to figure out if an interface/abstract class is better or not. I don't get the point of an interface if you can just use an abstract class with virtual abstract methods.
Here is an interface:
public interface IAthlete
{
void Run();
}
Here is an abstract class:
public abstract class Athlete
{
public abstract void Run();
}
Here is an implementation of the interface:
public class Sprinter : IAthlete
{
public void Run()
{
Console.WriteLine("Running Fast....");
}
}
Here is an extension of the abstract class:
public class MarathonRunner : Athlete
{
public override void Run()
{
Console.Write("Jogging....");
}
}
Now if I decide to add a method called Stop to either the interface or abstract method, Sprinter and MarathonRunner both break and because I can provide some default implementation to abstract, it seems like a better choice. Am I missing something?
There are 2 main differences between Interfaces and abstract super-classes:
Abstract Classes
code reuse is possible by using an abstract super-class
you can only inherit one super-class
Interfaces
every method has to be implemented in each sub-class
a class can inherit more than 1 interface (multiple inheritance)
In the case where all you have is one piece of commonality to extract, you're quite right that there isn't a substantive difference between the two. But this is rather like saying "in the case of adding 1 to 2, there's no difference between an int and a double" - it's technically true, but not a particularly useful guide to how to think.
In case with any more complexity than this (that is, in most cases) there will be more classes, and pieces of common baheaviour to extract. Then you have to start making a significant choice between class inheritance and interface implementation, taking into account things like:
you only get one shot at choosing a base class, but you can implement as many interfaces as you like
if you want your 'parent' to do any work, it needs to be a class not an interface
and so on.
In general, the semantics of your classes should guide you - where the 'things' have an "IS A" relationship (like MarathonRunner to Athlete), inheritance is suggested; where the 'things' have an "I CAN FULFIL THE CONTRACT OF A" (like, say, Person to Runner), interface implementation is suggested.
Interfaces are a btter way to go as the current consensus amongst the .NET developer comunity is that you should favour composition over inheritance, so Interfaces are a much better strategy (think of Injection Containers and how usefull they are as well, and lets not get started on unit testing).
also, classes can implement many interfaces but can only inherit from one class (abstract or otherwise). also structs can implement interfaces but not inherit from another class.
At the runtime level, interfaces are more efficient as the runtime doesnt have to walk the inheritance stack in order to work out the polymorphic implications of calling a specific member.
Interfaces are a very useful feature, and are very similar to abstract classes, and in some circumstances, exchangable with abstract classes.
But, don't jump straight to interfaces, unleass you have to (very common antipattern in Java developers). I suggest, by reading your example, to stick to abstract classes.
Most of the times I only use interfaces, when I have several non related classes, and I need them to have common members, as If these classes came from the same base class.
In your example, you are trying to find what happen if you need a new stop method, when adding a base virtual method. These can be solved in a different approach, that is not Abstract Classes versus interfaces.
There are 3 choices:
(1) Add an abstract method that coerce the programmer to override it, in order to instantiate objects.
(2) Add a new virtual method that does something, but doesn't have to be overriden.
(3) Add a new method that does nothing, maybe applies to your case.
// cannot instantiate an abstract class
public abstract class Athlete
{
// helper method:
public /* non-abstract */ void DoNothing()
{
// does nothing on purpouse !!!
}
// (1) virtual & abstract method, must be overriden
public abstract void Run();
// (2) new virtual method, doesn't need to be overriden,
// but, maybe you dont like what it does
public virtual void Stop()
{
Message.Show("Stop !!!");
}
// (3) new virtual method, doesn't need to be overriden,
// its safe to be called
public virtual void TakeBreak()
{
// works like an abstract virtual method, but, you don't need to override
DoNothing();
}
} // class Athlete
// in a non abstract class, you must override all abstract methods
public /* non-abstract */ class Runner: Athlete
{
public override void Run()
{
DoNothing();
}
public override void Stop()
{
DoNothing();
}
// don't need to override this method
// public virtual void TakeBreak();
} // class Trekker
// ...
Runner ARunner = new Runner();
ARunner.Run();
ARunner.Stop();
ARunner.TakeBreak();
The third kind of virtual method, that may apply to your example, doesnt' have a special name, I already post a question about it on stackoverflow, but, nobody knew an special name for this case.
Cheers.
An important difference between interfaces and abstract classes is how their members handle multi-generational inheritance. Suppose there's an abstract class BaseFoo with abstract method Bar and interface IFoo with method Boz; class Foo inherits BaseFoo and implements IFoo, and class DerivedFoo inherits from Foo.
If DerivedFoo needs to override BaseFoo.Bar, it may do so, and its override may call base.Bar() if it needs to use its parent's implementation. If Foo implements Boz implicitly using a virtual method, then DerivedFoo may override that method and call base.Boz() (the override being a function of the class rather than the interface) but if Foo explicitly implements IFoo.Boz, then the only way for DerivedFoo to change the behavior of IFoo.Boz will be to re-implement it. If it does so, then Foo's implementation of IFoo.Boz will become inaccessible, even within DerivedFoo's implementation of the same interface member.

where to put the GetItems static method? + inheritance question

I have Item class:
public class Item {
public long Id {get; protected set;}
public string Name {get; protected set;}
}
and now I want to add a function that retrieve items from the db according to filters. This should be static method that returns Item[]:
public static Item[] GetItems(long? itemId, string itemName) {
//Do Search in the db for items with Id=itemId (in case itemId is not null) and
//with Name=itemName (in case itemName is not null)
return itemsList.ToArray();
}
The question is where to put this method?
1. should I create a new class for this? How will I call this class?
2. should I put this method in Item class?
Another question:
In case I want to inherit from Item class. How can I force the child classes implement such GetItems method?
I would recommend a simple repository pattern implementation. You could create a class called ItemRepository that knows about your Item object and your DAL implementation. The repository would simply call into the DAL to get any data it needs and then return business objects back to the consumer.
This is very simple to implement, and if you create an interface to go along with it (ex: IItemRepository), unit testing becomes very easy because you'll be able to mock the repository and pass it along to any object that consumes it. If you make everything static, then testing is much harder, so I wouldn't recommend it.
As for inheritance: if you want to define general method signatures and properties that should be available on every Repository object, then use an interface to specify exactly what each repository should have in common. If you want to provide a base repository skeleton, then an abstract may be more fitting.
GetItems (plural) does not, to me, sound like something that should be a member of Item (singular). Especially since Item is so simple. I would create a static utility class (the factory pattern) called ItemUtility that has GetItems.
To answer your second question: if a class inherits from Item it will also inherit any concrete implementations of its member. So if there was a LoadItem method on Item, and I made SpecialItem : Item, then SpecialItem.LoadItem() would actually just be the Item.LoadItem() code. If you want to make Item.LoadItem() overridable then you can use the "virtual" modifier on the method (which would give SpecialItem the option of doing its own thing with that method).
Item could also be an abstract class if you only intend it to be used as a boilerplate base class for other more complex classes like SpecialItem.
Another option would be to create an IItem interface, and make LoadItem (and any other required member) part of the interface definition.
The data access should go in a separate class. Data access should be stored in a separate layer than the object definition, following the Separation of Concerns concept.
If you want to force all inherited objects to implement a method, you can make it abstract.
Is there any specific reason you want to make the method static? If you want to inherit the GetItems method in your child classes, you cannot make it static. To answer your questions in order:
1) Yes. Create a new class called something like ItemManager that makes the actual call to the DB layer to get the Items. That way you are separating your Data Access code from business logic
2) You should create a method in Item Class that calls the method in ItemManager to get the actual data.
3) Mark the method you created in step 2 as virtual if you want child classes to override the method to provide their own implementation. If you want to force them to override and need no implementation in the base class itself, then mark the base class as abstract so child class must override it

Inherit from a class or an abstract class

If you have several classes where you want them to inherit from a base class for common functionality, should you implement the base class using a class or an abstract class?
That depends, if you never want to be able to instantiate the base class then make it abstract. Otherwise leave it as a normal class.
If the base class ought not to be instantiated then make it an abstract class - if the base class needs to be instantiated then don't make it abstract.
In this example it makes sense to make the base class abstract as the base class does not have any concrete meaning:
abstract class WritingImplement
{
public abstract void Write();
}
class Pencil : WritingImplement
{
public override void Write() { }
}
However in this next example you can see how the base class does have concrete meaning:
class Dog
{
public virtual void Bark() { }
}
class GoldenRetriever : Dog
{
public override void Bark() { }
}
It is all pretty subjective really - you ought to be able to make a pretty good judgment call based on the needs of your particular domain.
It depends, does it make sense for the base class in question to exist on it's own without being derived from? If the answer is yes, then it should be a regular class, otherwise, it should be an abstract class.
I suggest:
Make an interface.
Implement the interface in your base class.
Make the base class a real class, not abstract (see below for why).
The reason I prefer real classes instead of abstract classes is that abstract classes cannot be instantiated, which limits future options unnecessarily. For example, later on I may need the state and methods provided by the base class but cannot inherit and do not need to implement the interface; if the base class is abstract I am out of luck, but if the base class is a regular class then I can create an instance of the base class and hold it as a component of my other class, and delegate to the instance to reuse the state/methods provided.
Yes this does not happen often, but the point is: making the base class abstract prevents this kind of reuse/solution, when there is no reason to do so.
Now, if instantiating the base class would somehow be dangerous, then make it abstract - or preferably make it less dangerous, if possible ;-)
Think of it like a bank account:
You can make a generic abstract base account called "Account", this holds basic information such as customer details.
You can then create two derived classes called "SavingAccount" or "DebitAccount" which can have their own specific behaviour whilst benefiting from the base class behaviour.
This is a situation where the customer must have either a Savings Account or a Debit Account, a generic "Account" is not allowed as it is not very popular in the real world to have just an account of no description.
If you can create a similar scenario for your needs, abstract is the way to go.
Abstract classes are for partially implemented classes.
By itself doesn't make sense to have an instance of an abstract class, it needs to be derived. If you would like to be able to create the base class it cannot be abstract.
I like to think of abstract classes as interfaces which have some members pre-defined since they are common to all sub-classes.
Think of this a different way
Is my a base class a complete object on it's own?
If the answer is no, then make it abstract. If it's yes then you likely want to make it a concrete class.
I would say if you are not planning on calling the base class by itself, the then you should define it as an abstract class.
The depends on whether you want the base class to be implemented on its own or not.
As an abstract class, you can't make objects from it.
Abstract classes are great for predefined functionality, for example - when know the minimum exact behaviour a class should expose but not what data it should use to do it or the exact implementation.
abstract class ADataAccess
{
abstract public void Save();
}
Normal (non abstract) classes can be great for similar things but you have to know the implementation specifics to be able to write them.
public class DataAccess
{
public void Save()
{
if ( _is_new )
{
Insert();
}
else if ( _is_modified )
{
Update();
}
}
}
Also, you could use interfaces (individually or on classes, whether abstract or not) to define the same sort of prototype definition.
interface ISaveable
{
void Save();
void Insert();
void Update();
}
class UserAccount : ISavable
{
void ISavable.Save() { ... }
void ISavable.Insert() { ... }
void ISavable.Update() { ... }
}
Yet another option may be using generics
class GenDataAccess<T>
{
public void Save()
{
...
}
}
All these methods can be used to define a certain prototype for classes to work with. Ways to make sure that code A can talk to code B. And of course you can mix and match all of the above to your liking. There is no definite right way but I like defining interfaces and abstract classes, then referring to the interfaces. That way eliminates some of the thought requirements for "plumbing" in higher level classes while keeping the maximum flexibility. (having interfaces takes away the requirement of using the abstract base class, but leaves it as an option).
I think a lot of you should resit basic OO classes again.
The basic underlying principle in OOA/OOD is to abstract abstract abstract, until you can't abstract no more. If what your looking at is an abstraction then so be it, thats what your OOA/OOD already told you. However if you sitting there wondering whether "code" should be abstract or not then you obviously don't know what the term means and should go learn basic OOA/OOD/OOP again :-)
More to the point you should learn Design Patterns and Harmonic Theory, this will help with your OO designs immensely!

Categories