As the ttitle said, im asking if is this a good programmation/design way.
I got a class, that can be just an Interface (only got 1 abstract method and few attributes)
As a example of my case, this is similar:
We got a main class Car than could be a truck, auto, moto, ...
and has an abstract method void move()
Could I design CAR as interface, and the other concrete classes as a generalization of CAR class? or is this wrong?
public interface Car{
private int length;
private float speed;
public void move();
}
public class truck : Car{
//Constructor
public Car(int size)
{
length=size;
}
public void move()
{
//Move code
}
}
and then
Car myCar = new truck();
myCar.move();
Would be right?
You're mixing up the terms "abstract" and "interface" here.
It is perfectly fine to refer to an instance of a class by the interface it implements. Here you see an interface, ICookieFactory which bakes abstract Cookies:
public interface ICookieFactory
{
Cookie BakeCookie();
}
public class ChocolateChipCookieFactory : ICookieFactory
{
public Cookie BakeCookie()
{
return new ChocolateChipCookie();
}
}
public abstract class Cookie
{
public abstract IEnumerable<Crumb> Crumble();
}
public class ChocolateChipCookie : Cookie
{
public override IEnumerable<Crumb> Crumble()
{
...
}
}
ICookieFactory factory = new ChocolateChipCookieFactory();
Cookie cookie = factory.BakeCookie();
foreach (Crumb crumb in cookie.Crumble())
{
...
}
An interface tells implementations of it which methods or properties it must support, but cannot provide any implementation code itself. You can't define fields in an interface.
An abstract class can include any number of fields and methods, and abstract methods that must be overridden by child classes.
A single class can implement multiple interfaces but only inherit from a single abstract class.
As far as i Know, yes, its possible and right to create an interface which child classes would be a case of generalization association.
But in my case, and thanks to the only answer of C.Evenhuis, i realized it'll be better to make an abstract class (so i can combine some abstract methods that child classes must override, with some concrete methods that childs can override or simply use).
Related
I was practicing c# abstract class and inheritance, but I was wondering if derived classes could access the constructor by calling the base
public abstract class A
{
protected bool value_A;
protected int value_B;
public A(int input)
{
A = true;
B = false;
}
public abstract int function_B();
}
}
public class childA : A
{
public childA (int input):base(input)
{
}
public override int function_B()
{
//do smth
}
}
public class childB : A
{
public childB(int input):base(input)
{
}
public override int function_B()
{
//do something different
}
public void functionC(int input)
{
}
}
I was confused if I should use this abstract class design or just go ez by using inheritance -> declare a virtual function in class A.
Yes, you can. Derived class c'tor can call base class one, even if the base class is abstract.
Generally, using abstract base class makes sense if there is a common functionality (or traits) that you want to reuse, and instantiating the base class does not make sense (and therefore you make it an abstract class).
A basic example is "Shapes" hierarchy, with abstract base class Shape that has color and center (for instance) and virtual method Draw, and all specific shapes inheriting from Shape and implementing the actual Draw functionality for each specific shape.
In case I want any class inherits/implements some methods which is better an interface or an abstract class contains these abstract methods only and acts as an interface. I know the difference between the interface and the abstract class well but in this case do the two have the same function or there are different something?
I think we can feel free to use one of them but still I take the side of interface because my aim is to enforce any class to implement these methods and it is the job of interface.
I agree an abstract class with no concrete behavior seems a little pointless so I would favour an interface.
Abstract classes are far more useful when bringing together some common behavior that cannot be overridden along with some elements that can eg) template methods
public abstract class Base
{
public void TemplateMethod()
{
AbstractMethod1();
AbstractMethod2();
}
public abstract void AbstractMethod1();
public abstract void AbstractMethod2();
}
public class Concrete : Base
{
public override void AbstractMethod1()
{
Console.Write("Override Abstract Method 1");
}
public override void AbstractMethod2()
{
Console.Write("Override Abstract Method 2");
}
}
public class Main
{
public Main()
{
var concrete = new Concrete();
concrete.TemplateMethod();
}
}
I created two abstract classes and tried to create a class that inherits from both. But I get an error message.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
abstract class AbstractClassTwo
{
public abstract void ShowMessage();
public abstract void DisplayPlace();
}
class DerivedClass : AbstractClassOne, AbstractClassTwo // here under AbstractClassTwo it shows the error "cannot have multiple base classes:"
{
}
So a class can only derive from one abstract class?
If can derive from more than one abstract class, then what happens if both classes define the same method, as is the case above (abstract class one and two both have a method showmessage(), so which one will be in the derived class)?
Multiple inheritance is not allowed by C# but it is allowed by C++.
To answer your question regarding the ShowMessage() method that is a known problem in c++ with multiple inheritance called "The Diamond Problem". see: http://en.wikipedia.org/wiki/Multiple_inheritance
So basically you will have to excitability state to which method you are refereeing when calling it e.g. ParentA::ShowMessage()
if you want to have a type that is polymorphic to 2 other types than you should create two separate interfaces and implement them. and if you want to reuse the same methods than you will have to use compositions.
Interfaces example:
public interface ISomeInterface
{
public void ShowMessage();
public void DisplayName();
}
public class ClassOne : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayName()
{
//implementation
}
}
public class ClassTwo : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayPlace()
{
//implementation
}
}
Interface with reusable Show Message Method using composition:
public class ClassTwo : ISomeInterface
{
private ISomeInterface _MyPrivateReusableComponent = new ClassOne();
public void ShowMessage()
{
_MyPrivateReusableComponent.ShowMessage()
}
public void DisplayPlace()
{
_MyPrivateReusableComponent.DisplayName()
//implementation
}
}
In C# it's not allowed to inherit from more than one class. To do what you want here, you need to use interfaces.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
Interface IClassTwo
{
void ShowMessage();
void DisplayPlace();
}
class DerivedClass : AbstractClassOne, IClassTwo
{
}
You can't inherit from more than one class (abstract or otherwise), but in your case the abstract classes are pretty much interfaces, so you can turn them into interfaces and inherit from them (you can inherit from any number of interfaces).
No, abstract class whether having all abstract methods or only some, makes no difference as far as inheritance in concerned. you can inherit only one class (in C#) and as many interfaces as you want.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Interface vs Abstract Class (general OO)
In one of the MSDN article following line is mentioned
Interfaces cannot specify new members in later versions while
abstract classes can add members as needed to support additional
functionality.
I picked this sentence from here. You can read the same sentence in paragraph 3.
I have a confusion, sorry in advance for in case I am missing something.
Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
Your comments?
Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
No, for an abstract class only the abstract methods need to be overridden. You can add non-abstract methods with no errors.
For example, version 1:
public abstract class FooBase
{
public abstract void Bar();
}
public class FooImpl : FooBase
{
public override void Bar() {}
}
Now introduce a new non-abstract method in FooBase for version 2:
public abstract class FooBase
{
public abstract void Bar();
public void NewMethod() {}
}
... and there's no problem.
Note that for company internal code, where all the code which is going to use the API is rebuilt at the same time, this is often not a problem at all, with either interfaces or abstract classes. If you want to add a method to an interface, you can do so as you can upgrade all implementations at the same time.
It's really when you don't have control over the whole code base that you need to be careful.
an class implementing an interface MUST implement all methods and properties defined in the interface.
when inheriting from an Abstract class, you MUST implement/override all the Abstract members, but any non-abstract members will be inherited just as when you inherit from a concrete class.
When you inherit from Interfaces, you must implement all members of that interface. But you can expand on the interface as you deem fit. You can also inherit multiple interfaces. Valid Example:
public interface IPerson
{
string FullName { get; set; }
string SSN { get; set; }
}
public interface IPersonDBContext
{
void Save(IPerson person);
}
public class PersonData : IPerson, IPersonDBContext
{
// Implements IPerson FullName
public string FullName { get; set; }
// Implements IPerson SSN
public string SSN { get; set; }
// Implements IPersonDBContext Save()
public void Save(IPerson person)
{
// Code to save the IPerson instance to the DB...
}
// Added method, not included in any interface...
public void Validate(IPerson person)
{
// Code to validate the IPerson instance...
}
}
Now, for Abstract classes, you can include concrete methods that can be inherited, but also specify some methods that must be overridden. However, note, you cannot have more than one Base Class (and an Abstract Class is still a class...) So you can't mix two abstract classes like you can an interface. Example:
public abstract class Person
{
public string FullName { get; set; }
public string SSN { get; set; }
public abstract void Save();
}
public class PersonData : Person
{
// Implements Abstract Person Save() Method
public override void Save()
{
// Save logic here...
}
// Non-inherited member...
public void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
}
Lastly, and most powerfully, you can mix a single abstract base class with as many interfaces as you want... So, If I kept the Abstract class Person, from example 2, and the Interface IPersonDBContext from example 1, I could do this:
public class PersonData : Person, IPersonDBContext
{
// Implements Abstract Person Save() Method
public override void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
// Inplmenets IPersonDBContext Save()
public void Save(Person person)
{
// Save logic here...
}
// Non-inhereted method
public void Clone(Person person)
{
// Logic to make a member-wise clone.
}
}
Hope that helps...
Implementing an interface forces you to override its methods - inheriting a class however gives you a choice. Only abstract methods needs to be overriden. The MSDN excerpt points out that the price of a strict interface contract can prove to be expensive later on, when all implementors will need to implement the added methods. Using a class parent with virtual methods let you decide later on whether you need a specialization.
I have an interface so class writers are forced to implement certain methods. I also want to allow some default implemented methods, so I create a abstract class. The problem is that all classes inherit from the base class so I have some helper functions in there.
I tried to write : IClass in with the abstract base, but I got an error that the base didn't implement the interface. Well of course because I want this abstract and to have the users implement those methods. As a return object if I use base I can't call the interface class methods. If I use the interface I can't access base methods.
How do I make it so I can have these helper classes and force users to implement certain methods?
Make sure methods in the base class have the same name as the interface, and they are public. Also, make them virtual so that subclasses can override them without hiding them.
interface IInterface {
void Do();
void Go();
}
abstract class ClassBase : IInterface {
public virtual void Do() {
// Default behaviour
}
public abstract void Go(); // No default behaviour
}
class ConcreteClass : ClassBase {
public override void Do() {
// Specialised behaviour
}
public override void Go() {
// ...
}
}
Move the interface methods into the abstract class and declare them abstract as well. By this, deriving classes are forced to implement them. If you want default behaviour, use abstract classes, if you want to only have the signature fixed, use an interface. Both concepts don't mix.
Having faced with the same problem recently, I've came up with a somewhat more elegant (to my mind) solution. It looks like:
public interface IInterface
{
void CommonMethod();
void SpecificMethod();
}
public abstract class CommonImpl
{
public void CommonMethod() // note: it isn't even virtual here!
{
Console.WriteLine("CommonImpl.CommonMethod()");
}
}
public class Concrete : CommonImpl, IInterface
{
void SpecificMethod()
{
Console.WriteLine("Concrete.SpecificMethod()");
}
}
Now, according to C# spec (13.4.4. Interface mapping), in the process of mapping IInterface on Concrete class, compiler will look up for CommonMethod in CommonImpl too, and it doesn't even have to be virtual in the base class!
The other significant advantage, compared to Mau's solution, is that you don't have to list every interface member in the abstract base class.