Relation has a, inheritance and casting - java

Lets suppose I have the following classes:
abstract class AbstractEngine{...}
abstract class AbstractTransmission {...}
abstract class AbstractCar {
private AbstractEngine engine;
private AbstractTransmission transmission;
//setters and getters
...
}
class ConcreteEngine extends AbstractEngine{...}
class ConcreteTransmission extends AbstractTransmission{...}
class ConcreteCar extends AbstractCar {
public void move() {
ConcreteEngine engine = (ConcreteEngine)getEngine();
ConcreteTransmission transmission = (ConcreteTransmission) getTransmission();
....
}
}
As you see in ConcreteCar we will have a lot of casting for working with concrete details. It seems to me that I am doing something wrong here. Can I anyhow avoid so many casting using has a relation and inheritance?

You are correct, such downcasts are most often a symptom of a bad design.
In your case - it seems that your abstractions are not good enough.
In other word: your base (abstract) classes should provide all the *behavior that one needs to deal with the corresponding object.
Meaning: to a user of AbstractEngine it should absolutely not matter what implementation is behind that object. Therefore: look into the interface that your abstract classes are offering; and rework them in a way that allows you to do the necessary things without instanceof checks and downcasts.
It might also be worthwhile to look into "splitting" your functionality into a set of interfaces; allowing you for more "fine granular" slicing of functionality.

I think this is a typical example for the usage of generics. You do not need type casting if you modify your code like this:
abstract class AbstractEngine{};
abstract class AbstractTransmission {};
abstract class AbstractCar<E extends AbstractEngine, T extends AbstractTransmission> {
private E engine;
private T transmission;
public E getEngine() {
return engine;
}
public T getTransmission() {
return transmission;
}
}
class ConcreteEngine extends AbstractEngine{};
class ConcreteTransmission extends AbstractTransmission{};
class ConcreteCar extends AbstractCar<ConcreteEngine, ConcreteTransmission> {
public void move() {
ConcreteEngine engine = getEngine();
ConcreteTransmission transmission = getTransmission();
}
}

You should make use of Polymorphism. Try
AbstractEngine engine = getEngine()
This will compile because ConcreteEngine is-a AbstractEngine. Also this is better OOP practice because this way your program will be more flexible to future changes.

Related

Java polymorphism: finding the right design pattern

Disclaimer: I know there are a lot of questions about polymorphism out there, but I couldn't find a suitable answer for my problem. If your Google-fu is better than mine, please forgive the dupe.
I have a model using inheritance, such as in the example below.
public abstract class Base {
// ...
}
public class ConcreteA extends Base {
private String someString;
// ...
}
public class ConcreteB extends Base {
private boolean someBool;
// ...
}
And I also have a List<Base>, which is composed of objects that are either ConcreteAs or ConcreteBs.
I need to generate a graphical view for each object in the list, but the resulting element is not the same for ConcreteAs and ConcreteBs. From the example above, the view for ConcreteA would be a text field, while the view for a ConcreteB would be a check box.
How can I achieve this using OO principles?
The problem that you have is that you somewhere return a List<Base> when the caller must know the concrete type.
Usually this is caused because one tried to make a method more generic. E.g. if someone has this service methods
public List<ConcreteA> doSomethingA(){ ... }
public List<ConcreteB> doSomethingB(){ ... }
he might think it is a better idea to introduce a superclass, Base so that both methods can be substituted by
public List<Base> doSomething(){ ... }
This is a good idea if the caller is only interessted in a Base object. This means that ConcreateA and ConcreteB have some common behavior that the caller only depends on.
But in your case it seems that the caller needs the concrete type information that is not available anymore, because of the more generic method.
So you either must preserve or reconstruct the type information.
Preserve the type by using a custom return type instead of making the method generic
public class Result {
private List<ConcreteA> concreteA;
private List<ConcreteB> concreteA;
}
public Result doSomething();
Recunstruct the type information using instanceof
Reconstruct the type information by introcucing a visitor pattern.
Not a pattern - this is what abstraction is all about. Declare a method you want all subclasses of Base to implement and each must implement it in their own way.
Obviously you would pass parameters and/or get results of the methods.
public abstract class Base {
abstract void graphicalView();
}
public class ConcreteA extends Base {
#Override
void graphicalView() {
}
}
public class ConcreteB extends Base {
#Override
void graphicalView() {
}
}
public void test() throws IOException {
List<Base> bases = new ArrayList<>();
for ( Base b : bases ) {
b.graphicalView();
}
}
I think you're looking for Visitor Design Pattern.
From Wikipedia :
In object-oriented programming and software engineering, the visitor
design pattern is a way of separating an algorithm from an object
structure on which it operates. A practical result of this separation
is the ability to add new operations to extant object structures
without modifying the structures. It is one way to follow the
open/closed principle.
In essence, the visitor allows adding new virtual functions to a
family of classes, without modifying the classes. Instead, a visitor
class is created that implements all of the appropriate
specializations of the virtual function. The visitor takes the
instance reference as input, and implements the goal through double
dispatch.
In such cases, I usually use generics something like this
public abstract class Base <T extends Shape>{
public abstract T drawShape();
}
public class ConcreatA extends Base<Circle> {
#Override
public Circle drawShape() {
return null;
}
}
public class ConcreatB extends Base<Square> {
#Override
public Square drawShape() {
return null;
}
}
So now you can use list of Shapes

Java - Is it possible to extend all the subclasses of a class with a single class?

Java - Is it possible to extend all the subclasses of a class with a single class?
Let's explain it with an example, the actual code is quite more complex. I have an Animal class with its own class hierarchy. Let's say that it has two subclasses: Testarrosa and Viper.
public class Car {
public abstract String getManufacturer();
}
public class Testarossa extends Car{
public String getManufacturer(){
return "Ferrari";
}
}
public class Viper extends Car{
public String getManufacturer(){
return "Dodge";
}
}
I want to extend all the Car subclasses with a RegisteredCar subclass.
public class RegisteredCar extends Car {
private String plateNumber;
public RegisteredCar (String plateNumber){
this.plateNumber=plateNumber;
}
public String getPlateNumber() {
return plateNumber;
}
}
At some point, I should be able to create a new RegisteredCar of a specific subclass. Something like
RegisteredCar c = new RegisteredCar<Viper>("B-3956-AC");
And call the c.getManufacturer() to obtain "Dodge" and c.getPlateNumber() to obtain B-3956-AC. Obviously, I should still be able to create a Car c = new Viper();
That is an example. Having an attribute in Car with null value if not registered is not enough for what I need.
In short, no that is not possible. You have to unfortunately modify your object model.
For example, what about having a Registration class this way:
public interface Registration<C extends Car> {
C getCar();
String getPlateNumber();
}
This way you can extract the information relating to registration in a single class, while maintaining your Car models.
You can then do helper methods like:
Registration<Viper> registeredViper = createRegistration(new Viper(), "B-3956-AC");
As others have said, no thats not really possible and your example could be solved by changing your model
As an alternative to inheritance you could use another class to wrap a Car instance.
I would make Car an interface (though having RegisteredCar extend Car should work too) and then attempt something like the following pseudo code:
class RegisteredCar<T extends Car> implements Car {
private final T car
RegisteredCar(T car) {
this.car = car;
}
... methods for RegisteredCar
... methods from Car delegating to `this.car`
}
Please excuse the somewhat bad code, I don't have an IDE open, and I always mess up generics without an IDE to hand.
Another possible solution is to use AOP, though I don't know how in fashion that is these days as but what you are describing could be a cross cutting concern.
A final alternative might be to use a language that allows for Extensions, Traits, Protocol or some other type of 'mix in'
In java it is prohibited to extends more than 1 class.
You could build chain from classes to extends, for example.
To solve the problem of mutiple inheritance in Java → interface is used
You should avoid inheritance as much as possible. Use abstractions (interfaces) to make your code elegant and maintainable. Just google why extends is evil.
public interface Car{
String getManufacturer();
}
public interface Registerable{
boolean isRegistered();
void register(String plateNumber);
void getPlateNumber();
}
public class Viper implements Car, Registerable
{
//all methods
}
With Generic class approach as described in other answer, you will not be able to use RegisteredCar where your require to pass Car object. e.g. suppose you need to generate some invoice.
Invoice getInvoice(Car c);
In this method you cannot use RegisteredCar as it is not of Type Car. All you API which require Car are not applicable to RegisteredCar. In some cases you may need Plate Number as well as Car, There you may need to keep mapping of Plate Number and Cars. I would suggest following approach based on Decorate Pattern and delegate all Car calls to passed car object
public class RegisteredCar extends Car{
public RegisteredCar(Car c, String plateNumber){
}
#Override
String getColor(){
c.getColor();
}
}
No, it's not like C++. Multiple inheritance is not possible in Java. However you can implement multiple interfaces.
You cannot achieve that with inheritance.
Your best option is making the RegisteredCar type generic, then having a generic instance variable that holds the intended type car:
public class RegisteredCar<T extends Car> {
private String plateNumber;
private T car;
public T getCar() {
return this.car;
}
public T setCar(T car) {
this.car = car;
}
public RegisteredCar (String plateNumber){
this.plateNumber=plateNumber;
}
public String getPlateNumber() {
return plateNumber;
}
}
With this, you will be able to pass into RegisteredCar an object of any type that's a subclass of Car.
As you can notice, I have removed the extends Car part of this class, as it doesn't need to be a subclass of car itself.
Is there a reason, in the real classes, that you couldn't simply add the new feature to the existing base class?
public abstract class Car
{
public abstract String getManufacturer() ;
protected String plate_number = null ;
public String getPlateNumber()
{ return this.plate_number ; }
public boolean isRegistered()
{ return ( this.plate_number != null ) ; }
}

How to design a common static method in all classes implementing an interface

I have an interface called Relation, implemented by a class BasicRelation, and extended by subclasses (e.g. ParentChild, Sibling, Spouse). While developing my code, I realized that I often need a method which takes a String representation of a relation to create it. For example:
public class ParentChild implements Relation extends BasicRelation {
// e.g. "Jack is Emily's father. Jill is her mother." will return the list
// <ParentChild(Jack, Emily), ParentChild(Jill, Emily)>
static List<ParentChild> fromSentence(String s) {
...
}
}
Now, since I find myself needing this method (fromSentence(String)) in every class, except perhaps in BasicRelation, I would like to move it up the hierarchy. The problem is that the internal details of the method is subclass-dependent, so I can't have it as a static method in the interface Relation or the superclass BasicRelation.
Unfortunately, in Java, it is also not possible to have a static abstract method.
Is there any way to ensure that every subclass of BasicRelation (or every class implementing Relation) implements fromSentence(String)? If no, should I be designing this in a completely different way? I guess this last question is more of a request for design-advice than a question.
Why does the static method need to be in the interface? What's stopping you from having a 'Utility' class and having the method in there?
public class RelationUtility {
public static BasicRelation relationFactory(String asString) {
....
}
}
As a static method, there is no reason other than access to private members, which can also be accomplished by by 'default' permissions on those members....
You can try making the BasicRelation class an abstract class and use an abstract fromSentence(..) method. This would require the ParentChild class to override and implement the fromSentence method because you can't create an object for ParentChild without implementing fromSentence()
public abstract class BasicRelation extends Relation(){
public abstract List<..> fromSentence(String s);
}
public class ParentChild implements Relation extends BasicRelation {
fromSentence(){
//parentChild class's implementation
}
}
If I understood right... you can try an approach like this
public class BasicRelation {
public abstract List<ParentChild> fromSentenceInSubclass(s);
public List<ParentChild> fromSentence(String s){
fromSentenceInSubclass(s);
}
}
And then you could have:
public class SubclassRelation extends BasicRelation {
public List<ParentChild> fromSentenceInSubclass(s){
// do subclass relation stuff
}
}
You will probably need to change the code a bit and add some Generics around to make it happen the way you want.
Sotirios Delimanolis Factory suggestion might also be an option.
You can have the abstract class BasicRelation include the static method which throws an Exception. That way you will be forced to override (shadow) the static method in the subclasses when you use it.
Something like:
public abstract class BasicRelation {
public static List<..> fromSentence(String s) {
throw new RuntimeException();
}
}

Java Multiple Inheritance

In an attempt to fully understand how to solve Java's multiple inheritance problems I have a classic question that I need clarified.
Lets say I have class Animal this has sub classes Bird and Horse and I need to make a class Pegasus that extends from Bird and Horse since Pegasus is both a bird and a horse.
I think this is the classic diamond problem. From what I can understand the classic way to solve this is to make the Animal, Bird and Horse classes interfaces and implement Pegasus from them.
I was wondering if there was another way to solve the problem in which I can still create objects for birds and horses. If there was a way to be able to create animals also that would be great but not necessary.
You could create interfaces for animal classes (class in the biological meaning), such as public interface Equidae for horses and public interface Avialae for birds (I'm no biologist, so the terms may be wrong).
Then you can still create a
public class Bird implements Avialae {
}
and
public class Horse implements Equidae {}
and also
public class Pegasus implements Avialae, Equidae {}
Adding from the comments:
In order to reduce duplicate code, you could create an abstract class that contains most of the common code of the animals you want to implement.
public abstract class AbstractHorse implements Equidae {}
public class Horse extends AbstractHorse {}
public class Pegasus extends AbstractHorse implements Avialae {}
Update
I'd like to add one more detail. As Brian remarks, this is something the OP already knew.
However, I want to emphasize, that I suggest to bypass the "multi-inheritance" problem with interfaces and that I don't recommend to use interfaces that represent already a concrete type (such as Bird) but more a behavior (others refer to duck-typing, which is good, too, but I mean just: the biological class of birds, Avialae). I also don't recommend to use interface names starting with a capital 'I', such as IBird, which just tells nothing about why you need an interface. That's the difference to the question: construct the inheritance hierarchy using interfaces, use abstract classes when useful, implement concrete classes where needed and use delegation if appropriate.
There are two fundamental approaches to combining objects together:
The first is Inheritance. As you have already identified the limitations of inheritance mean that you cannot do what you need here.
The second is Composition. Since inheritance has failed you need to use composition.
The way this works is that you have an Animal object. Within that object you then add further objects that give the properties and behaviors that you require.
For example:
Bird extends Animal implements IFlier
Horse extends Animal implements IHerbivore, IQuadruped
Pegasus extends Animal implements IHerbivore, IQuadruped, IFlier
Now IFlier just looks like this:
interface IFlier {
Flier getFlier();
}
So Bird looks like this:
class Bird extends Animal implements IFlier {
Flier flier = new Flier();
public Flier getFlier() { return flier; }
}
Now you have all the advantages of Inheritance. You can re-use code. You can have a collection of IFliers, and can use all the other advantages of polymorphism, etc.
However you also have all the flexibility from Composition. You can apply as many different interfaces and composite backing class as you like to each type of Animal - with as much control as you need over how each bit is set up.
Strategy Pattern alternative approach to composition
An alternative approach depending on what and how you are doing is to have the Animal base class contain an internal collection to keep the list of different behaviors. In that case you end up using something closer to the Strategy Pattern. That does give advantages in terms of simplifying the code (for example Horse doesn't need to know anything about Quadruped or Herbivore) but if you don't also do the interface approach you lose a lot of the advantages of polymorphism, etc.
I have a stupid idea:
public class Pegasus {
private Horse horseFeatures;
private Bird birdFeatures;
public Pegasus(Horse horse, Bird bird) {
this.horseFeatures = horse;
this.birdFeatures = bird;
}
public void jump() {
horseFeatures.jump();
}
public void fly() {
birdFeatures.fly();
}
}
May I suggest the concept of Duck-typing?
Most likely you would tend to make the Pegasus extend a Bird and a Horse interface but duck typing actually suggests that you should rather inherit behaviour. As already stated in the comments, a pegasus is not a bird but it can fly. So your Pegasus should rather inherit a Flyable-interface and lets say a Gallopable-interface.
This kind of concept is utilized in the Strategy Pattern. The given example actually shows you how a duck inherits the FlyBehaviour and QuackBehaviour and still there can be ducks, e.g. the RubberDuck, which can't fly. They could have also made the Duck extend a Bird-class but then they would have given up some flexibility, because every Duck would be able to fly, even the poor RubberDuck.
Technically speaking, you can only extend one class at a time and implement multiple interfaces, but when laying hands on software engineering, I would rather suggest a problem specific solution not generally answerable. By the way, it is good OO practice, not to extend concrete classes/only extend abstract classes to prevent unwanted inheritance behavior - there is no such thing as an "animal" and no use of an animal object but only concrete animals.
In Java 8 and later, you could use default methods to achieve a sort of C++-like multiple inheritance.
You could also have a look at this tutorial which shows a few examples that should be easier to start working with than the official documentation.
It is safe to keep a horse in a stable with a half door, as a horse cannot get over a half door. Therefore I setup a horse housing service that accepts any item of type horse and puts it in a stable with a half door.
So is a horse like animal that can fly even a horse?
I used to think a lot about multiple inheritance, however now that I have been programming for over 15 years, I no longer care about implementing multiple inheritance.
More often than not, when I have tried to cope with a design that pointed toward multiple inheritance, I have later come to release that I had miss understood the problem domain.
OR
If it looks like a duck and quacks like a duck but it needs
batteries, you probably have the wrong abstraction.
Java does not have a Multiple inheritance problem, since it does not have multiple inheritance. This is by design, in order to solve the real multiple inheritance problem (The diamond problem).
There are different strategies for mitigating the problem. The most immediately achievable one being the Composite object that Pavel suggests (essentially how C++ handles it). I don't know if multiple inheritence via C3 linearization (or similar) is on the cards for Java's future, but I doubt it.
If your question is academic, then the correct solution is that Bird and Horse are more concrete, and it is false to assume that a Pegasus is simply a Bird and a Horse combined. It would be more correct to say that a Pegasus has certain intrinsic properties in common with Birds and Horses (that is they have maybe common ancestors). This can be sufficiently modeled as Moritz' answer points out.
I think it depends very much on your needs, and how your animal classes are to be used in your code.
If you want to be able to make use of methods and features of your Horse and Bird implementations inside your Pegasus class, then you could implement Pegasus as a composition of a Bird and a Horse:
public class Animals {
public interface Animal{
public int getNumberOfLegs();
public boolean canFly();
public boolean canBeRidden();
}
public interface Bird extends Animal{
public void doSomeBirdThing();
}
public interface Horse extends Animal{
public void doSomeHorseThing();
}
public interface Pegasus extends Bird,Horse{
}
public abstract class AnimalImpl implements Animal{
private final int numberOfLegs;
public AnimalImpl(int numberOfLegs) {
super();
this.numberOfLegs = numberOfLegs;
}
#Override
public int getNumberOfLegs() {
return numberOfLegs;
}
}
public class BirdImpl extends AnimalImpl implements Bird{
public BirdImpl() {
super(2);
}
#Override
public boolean canFly() {
return true;
}
#Override
public boolean canBeRidden() {
return false;
}
#Override
public void doSomeBirdThing() {
System.out.println("doing some bird thing...");
}
}
public class HorseImpl extends AnimalImpl implements Horse{
public HorseImpl() {
super(4);
}
#Override
public boolean canFly() {
return false;
}
#Override
public boolean canBeRidden() {
return true;
}
#Override
public void doSomeHorseThing() {
System.out.println("doing some horse thing...");
}
}
public class PegasusImpl implements Pegasus{
private final Horse horse = new HorseImpl();
private final Bird bird = new BirdImpl();
#Override
public void doSomeBirdThing() {
bird.doSomeBirdThing();
}
#Override
public int getNumberOfLegs() {
return horse.getNumberOfLegs();
}
#Override
public void doSomeHorseThing() {
horse.doSomeHorseThing();
}
#Override
public boolean canFly() {
return true;
}
#Override
public boolean canBeRidden() {
return true;
}
}
}
Another possibility is to use an Entity-Component-System approach instead of inheritance for defining your animals. Of course this means, that you will not have individual Java classes of the animals, but instead they are only defined by their components.
Some pseudo code for an Entity-Component-System approach could look like this:
public void createHorse(Entity entity){
entity.setComponent(NUMER_OF_LEGS, 4);
entity.setComponent(CAN_FLY, false);
entity.setComponent(CAN_BE_RIDDEN, true);
entity.setComponent(SOME_HORSE_FUNCTIONALITY, new HorseFunction());
}
public void createBird(Entity entity){
entity.setComponent(NUMER_OF_LEGS, 2);
entity.setComponent(CAN_FLY, true);
entity.setComponent(CAN_BE_RIDDEN, false);
entity.setComponent(SOME_BIRD_FUNCTIONALITY, new BirdFunction());
}
public void createPegasus(Entity entity){
createHorse(entity);
createBird(entity);
entity.setComponent(CAN_BE_RIDDEN, true);
}
you can have an interface hierarchy and then extend your classes from selected interfaces :
public interface IAnimal {
}
public interface IBird implements IAnimal {
}
public interface IHorse implements IAnimal {
}
public interface IPegasus implements IBird,IHorse{
}
and then define your classes as needed, by extending a specific interface :
public class Bird implements IBird {
}
public class Horse implements IHorse{
}
public class Pegasus implements IPegasus {
}
Ehm, your class can be the subclass for only 1 other, but still, you can have as many interfaces implemented, as you wish.
A Pegasus is in fact a horse (it is a special case of a horse), which is able to fly (which is the "skill" of this special horse). From the other hand, you can say, the Pegasus is a bird, which can walk, and is 4legged - it all depends, how it is easier for you to write the code.
Like in your case you can say:
abstract class Animal {
private Integer hp = 0;
public void eat() {
hp++; 
}
}
interface AirCompatible {
public void fly();
}
class Bird extends Animal implements AirCompatible {
#Override
public void fly() {
//Do something useful
}
}
class Horse extends Animal {
#Override
public void eat() {
hp+=2; 
}
}
class Pegasus extends Horse implements AirCompatible {
//now every time when your Pegasus eats, will receive +2 hp
#Override
public void fly() {
//Do something useful
}
}
Interfaces don't simulate multiple inheritance. Java creators considered multiple inheritance wrong, so there is no such thing in Java.
If you want to combine the functionality of two classes into one - use object composition. I.e.
public class Main {
private Component1 component1 = new Component1();
private Component2 component2 = new Component2();
}
And if you want to expose certain methods, define them and let them delegate the call to the corresponding controller.
Here interfaces may come handy - if Component1 implements interface Interface1 and Component2 implements Interface2, you can define
class Main implements Interface1, Interface2
So that you can use objects interchangeably where the context allows it.
So in my point of view, you can't get into diamond problem.
As you will already be aware, multiple inheritance of classes in Java is not possible, but it's possible with interfaces. You may also want to consider using the composition design pattern.
I wrote a very comprehensive article on composition a few years ago...
https://codereview.stackexchange.com/questions/14542/multiple-inheritance-and-composition-with-java-and-c-updated
Define interfaces for defining the capabilities. You can define multiple interfaces for multiple capabilities. These capabilities can be implemented by specific Animal or Bird.
Use inheritance to establish relationships among classes by sharing non-static and non-public data/methods.
Use Decorator_pattern to add capabilities dynamically. This will allow you to reduce number of inheritance classes & combinations.
Have a look at below example for better understanding
When to Use the Decorator Pattern?
To reduce the complexity and simplify the language, multiple inheritance is not supported in java.
Consider a scenario where A, B and C are three classes. The C class inherits A and B classes. If A and B classes have same method and you call it from child class object, there will be ambiguity to call method of A or B class.
Since compile time errors are better than runtime errors, java renders compile time error if you inherit 2 classes. So whether you have same method or different, there will be compile time error now.
class A {
void msg() {
System.out.println("From A");
}
}
class B {
void msg() {
System.out.println("From B");
}
}
class C extends A,B { // suppose if this was possible
public static void main(String[] args) {
C obj = new C();
obj.msg(); // which msg() method would be invoked?
}
}
To solve the problem of mutiple inheritance in Java → interface is used
J2EE (core JAVA) Notes By Mr. K.V.R Page 51
Day - 27
Interfaces are basically used to develop user defined data types.
With respect to interfaces we can achieve the concept of multiple inheritances.
With interfaces we can achieve the concept of polymorphism, dynamic binding and hence we can improve the performance of a JAVA program in
turns of memory space and execution time.
An interface is a construct which contains the collection of purely
undefined methods or an interface is a collection of purely abstract
methods.
[...]
Day - 28:
Syntax-1 for reusing the features of interface(s) to class:
[abstract] class <clsname> implements <intf 1>,<intf 2>.........<intf n>
{
variable declaration;
method definition or declaration;
};
In the above syntax clsname represents name of the class which is
inheriting the features from ‘n’ number of interfaces. ‘Implements’ is
a keyword which is used to inherit the features of interface(s) to a
derived class.
[...]
Syntax-2 inheriting ‘n’ number of interfaces to another interface:
interface <intf 0 name> extends <intf 1>,<intf 2>.........<intf n>
{
variable declaration cum initialization;
method declaration;
};
[...]
Syntax-3:
[abstract] class <derived class name> extends <base class name> implements <intf 1>,<intf 2>.........<intf n>
{
variable declaration;
method definition or declaration;
};
Problem not solved. To sufficiently model this out and to prevent code replication you'd either need multiple inheritance or mixins. Interfaces with default functions are not sufficient because you cannot hold members in interfaces.
Interface modeling leads to code replication in subclasses or statics, which is both evil.
All you can do is to use a custom construction and split it up in more components and compose it all together...
toy language

java: inheritance

What are some alternatives to inheritance?
Effective Java: Favor composition over inheritance. (This actually comes from Gang of Four, as well).
The case he makes is that inheritance can cause a lot of unseemly side effects, if the extended class was not explicitly designed to be inherited. For example, any calls to super.someMethod() can lead you through unexpected paths of unknown code.
Instead, hold a reference to the class you would have otherwise extended, and delegate to it.
Here is a link to an interview with Erich Gamma where he talks about the concept a bit.
Some alternatives:
Delegation, also known as Composition
Wikipedia article on limitations and alternatives to inheritance
Q:Inheritance seems error-prone. How can I guard against these errors? And, what are the alternatives?
I'm assuming you're playing with Java which has some rules about inheritance.
Implementing interfaces is a common and oft used option. So, for example, if you have a data-source class that talks to a RDBMS, rather than inheriting that class and using it to implement a NoSQL datasource, the both can implement the same interface.
Rather than..
public class RDBMSDataSource {
...
public String loadSomeDataFromDataSource() {
...Do some stuff...
}
}
public class NoSQLDataSource extends RDBMSDataSource {
...
#Override
public String loadSomeDataFromDataSource() {
...Do some other stuff...
}
}
public class DataSourceClient {
public void foo() {
RDBMSDataSource ds = new NoSQLDataSource();
ds.loadSomeDataFromDataSource();
}
}
Which works but is hard to read, you could use this...
public interface DataSource {
public String loadSomeDataFromDataSource();
}
public class RDBMSDataSource implements DataSource {
...
public String loadSomeDataFromDataSource() {
...Do some stuff...
}
}
public class NoSQLDataSource implements DataSource {
...
#Override
public String loadSomeDataFromDataSource() {
...Do some other stuff...
}
}
public class DataSourceClient {
public void foo() {
DataSource ds = new NoSQLDataSource();
ds.loadSomeDataFromDataSource();
}
}
Another option would be composition. Say you have employees and customers. Your two options would be...
public class Person {
protected String name;
protected String address;
...More stuff...
}
public class Employee extends Person {
protected String jobCode;
protected String department;
...More stuff...
}
public class Customer extends Person {
protected String salesPerson;
protected Date registrationDate;
...More stuff...
}
...or...
public class ContactInfo {
private String name;
private String address;
...More stuff...
}
public class Employee {
private ContactInfo contactInfo;
private String jobCode;
private String department;
...More stuff...
}
public class Customer {
private ContactInfo contactInfo;
private String salesPerson;
private Date registrationDate;
...More stuff...
}
Since Java does not have multiple inheritance and you can implement multiple interfaces, you sometimes need to do the above to make sure your development is clean and readable.
I realise this is not Java per se, but Scala (a language running on the Java Virtual Machine) permits mixins (known as traits in Scala).
Mixins allow you to slot some functionality alongside an existing class, rather than within the inheritance tree.
When a class includes a mixin, the
class implements the interface and
includes, rather than inherits, all
the mixin's attributes and methods.
They become part of the class during
compilation
Delegation is an alternative to inheritance.
I think you should try delegation, delegation is an alternative to inheritance. Delegation means that you include an instance of another class as an instance variable. and it plays a beneficial role that it doesn't force you to accept all the methods of the super class.
Try Delegation which is also know as Composition
Also found the new alternative as mixin
The mixins are kind of composable abstract classes. They are used in a multi-inheritance context to add services to a class. The multi-inheritance is used to compose your class with as many mixins as you want. For example, if you have a class to represent houses, you can create your house from this class and extend it by inheriting from classes like Garage and Garden. Here is this example written in Scala:
val myHouse = new House with Garage with Garden
You will get more info about mixin https://kerflyn.wordpress.com/2012/07/09/java-8-now-you-have-mixins/

Categories

Resources