1

I am new to object oriented design and learning about interfaces and design patterns. In this example, I am trying to create class for cars. My question:

Is it good practice to use base class and then inherit from it. And then use interfaces for implementing different functions? If not, then what would be the best way to implement this.

Base Class:

    class BaseCar
        {
            public string color { get; set; }
            public double price { get; set; }

            public string carType { get; set; }
        }

Interface: 
interface ICarFunctions
    {
        void brakeSystem();

        void drivingModes(string mode);

        void entertainmentSystem();

    }

Now I am trying to create concrete classes

 class BmwCar : BaseCar, ICarFunctions
    {

        public void brakeSystem()
        {
            Console.WriteLine("Brake in less than 0.02ms");
        }

        public void drivingModes(string mode)
        {
            switch(mode) 

            {
                case "mountain":
                    {
                        Console.WriteLine("Switching to 4x4 mode");
                        break;
                    }

                default:
                    {
                        Console.WriteLine("Normal Mode");
                        break;
                    }

            }

        }

        public void entertainmentSystem()
        {
            Console.WriteLine("Music, Navigation");
        }
    }

Now my question is: Is it good practice to use a base class and then inherit from it? And then use interfaces for implementing different functions?

My second question is if interface should have only one function (Single responsibility principle) or can it can have multiple functions which need to be implemented?

1

Your first question

Is it good practice to use base class and then inherit from it. And then use interfaces for implementing different functions?

There is no inherent requirement which states that methods should be implemented via an interface and fields/properties should be inherited/defined in the class. This is not a good way to separate the logic, as you're essentially preventing any meaningful relation to exist between a class' fields/properties and its methods.

One obvious limitation is that interfaces only deal with public members. If you applied your approach to the letter, it would be impossible to use private class methods.

Similarly, you'd be unable to define a public property via an interface, which is going to hamper the usability of your interfaces. As a simple example, IList exposes public properties like Count and IsReadOnly. Could you technically handle that by using methods (GetCount() and IsReadOnly())? Sure, but what is the point of forcing yourself to only using methods for public access? Public properties exist for a reason: to severely cut down on the boilerplate getFoo()/setFoo() methods that you'd end up having to write for every publically accessible field you want.

Another limitation is that your code never defines that a BaseCar has a brakeSystem() method. For example, there is no problem with making a BaseCar that does not implement the necessary interface.

public class FlaterCar : BaseCar { }

The compiler has no issue with this. You never stated that you expect both the base class and interface to be used in conjuction with each other. This means that you're unable to create a method which is able to handle any BaseCar and make it brake. This is impossible:

public void MakeThisCarBrake(BaseCar car)
{
    car.brakeSystem(); //compiler error, brakeSystem is not a known method of BaseCar
}

This means that your base class has become impossible to use for a lot of common polymorphism use cases, and you would end up constantly having to do if(car is ICarFuntions) car.brakeSystem();, which violates LSP and OCP.

What you would expect is to be able to handle your base type without needing to guess about any interfaced the actual derived type might implement.

public void LetThisAnimalMakeASound(Animal animal)
{
    animal.MakeSound();
}

But this requires both the base and derived class to share the same method signature (regardless of whether the derived classes override the base class' method body or not).

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine(" ...silence... ");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Woof woof!");
    }
}

public class Duck : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Quack!");
    }
}

When you do put your methods in an interface, the only way to ensure that this still works is to have the base class implement the interface.

public interface IMakeSound
{
    void MakeSound();
}

public class Animal : IMakeSound
{
    public virtual void MakeSound()
    {
        Console.WriteLine(" ...silence... ");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Woof woof!");
    }
}

The derived class doesn't directly implement the interface itself, it merely inherits the interface implementation from its base class (and then chooses to override it, but that's not a requirement, it could choose to keep the base method as is).

But when you get to that point, you might not even need the interface anymore since you're already stuck having to define the implementation in the base class anyway, which means the interface might be a pointless second layer; unless this interface is used in many different classes and has its own (different) fuctional purpose compared to the base class.


Your second question

My second question is that should interface have only one function(Single responsibility principle) or it can have multiple functions to be implemented.

There is no rule about the amount of methods. It's all about the functional independence. For more information, read up on the interface segregation principle (ISP), the I in SOLID. (Note: I just picked one link, many other references exist).

In essense, it boils down to whether your interface can be split or not. Let's take your case:

public interface ICarFunctions
{
    void brakeSystem();
    void drivingModes(string mode);
    void entertainmentSystem();
}

The first question you should ask yourself: is this a package deal? Does every car with a brake system have an entertainment system? Does every car with a driving mode have brakes?

The contextual answer here is no. There is no inherent requirement that when you have brakes, you must have an entertainment system, and thus this interface can be split into separate interfaces.

However, that's not the same as saying that an interface can only have one method. There are cases where you cannot split an interface, e.g.:

public interface IEntertainmentSystem
{
    void IncreaseVolume();
    void DecreaseVolume();
    void Play();
    void Pause();
    void Previous();
    void Next();
}

These standard media player functions can be considered a package deal. It makes no sense to only have some of these features. Therefore, this interface should not be split up any further since it would not make sense to use only a subset of these functionalities and not the rest.

0

Is it good practice to use base class and then inherit from it. And then use interfaces for implementing different functions?

You're showing a base class for the purposes of providing remembered state, and an interface for offering methods.  The concrete class then extends the "base with state" and also implements the interface that provides some behaviors.  And you're asking if this is good practice.  The answer is that while this is fine in some circumstances, it is not the only way to go.  In the example that you're showing, this is unnecessary abstraction — though you may very well be using the abstractions being offered (not shown), their usage doesn't come across in the examples provided.  There is no reason to do this on its own — while nothing wrong with it, it should be motivated by more than the simpler example you're showing here.

You could have just as easily shown us an example where the base also implements the interface providing a default implementation, so that BMW and other similar subclasses would not need to implement much further at all.  (If we took the above given example as the end effort, we might say the base class and interface were not even needed.)


As often happens with these things, it depends on context.  First and foremost in my mind is how these are used by the consuming programmer — it should be dead easy to create and used these for the consuming client programmer — second how they are used by the programmers that implement subclasses deriving from the common base, and, third (and last) by how the base is defined.  I look at this as a pyramid where the most users (at the bottom) should be provided with the easiest to use abstractions, if necessary (though usually not) at the expense of the code at the tip of the pyramid written by only one programmer.

0

No and no.

It is not ok to use a base class for the purposes of holding data for the subclasses. It is actually contrary to object-orientation in general to have public properties. Object-orientation deals with behavior and considers data implementation detail.

Interfaces are not limited to one method and it isn't considered better or worse than a limited set of methods. Also single responsibility != single method. Instead of "single responsibility" I would suggest to use the better defined "coupling" and "cohesion" concepts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.