How to implement overlapping inheritance in Java? - java

I am wondering how to convert overlapping type of inheritance to Java. I got abstract class Person, and 2 extending subclasses: Driver and Passenger. As you know, driver may also be a passenger. So the question is: what's the best way to implement overlapping in Java? I heard that the best way is to use the composition, but i don't know how to.

When a single class can play two roles in a system, an inheritance-based approach in Java is to define two interfaces, and have the class implement them:
interface Passenger {
... // Methods applicable to passengers
}
interface Driver {
... // Methods applicable to drivers
}
class Person implements Driver, Passenger {
... // A person can be a driver or a passenger
}
class Pet implements Passenger {
... // A pet can be only a passenger
}
You can use composition internally to implement the interfaces by forwarding method calls to private helper "passenger" and "driver" objects inside Person.
In Java-8 you can place logic that is common to all implementing classes into default method implementations.

This is an extension of the answer provided by dasblinkenlight.
The solution is based on the component pattern described here by the Team Leader of the Tony Hawk dev team back in the '90s and it's often used in game development.
Disclaimer: I'm going to write the code without a Java compiler so please do tell me whether there are syntax errors.
Your abstract class Person
abstract class Person {
public String name;
}
This way we expose the behaviour of Driver
interface DriverInterface {
public void drive();
}
And here we export the behaviour of Passenger
interface PassengerInterface {
public void seat();
}
Here we put the actual logic of a Driver
class DriverComponent {
private Person person;
public DriverComponent(Person person) {
self.person = person;
}
public void drive() {
System.out.println("I'm" + person.name + " and I'm driving");
}
}
And here we put the logic of Passenger
class PassengerComponent {
private Person person;
public PassengerComponent(Person person) {
self.person = person;
}
public void drive() {
System.out.println("My name is " + person.name + " and I'm passenger");
}
}
Finally the Driver class
class Driver extends Person implements DriverInterface, PassengerInterface {
private DriverComponent driverComponent;
private PassengerComponent driverComponent;
private String name;
public Person(String name) {
driverComponent = DriverComponent(this);
passengerComponent = PassengerComponent(this);
}
public void drive() {
driverComponent.drive();
}
public void seat() {
passengerComponent.seat();
}
}
And the Passenger class
class Passenger extends Person implements Passenger {
private DriverComponent driverComponent;
private PassengerComponent driverComponent;
public String name;
public Passenger(String name) {
driverComponent = DriverComponent(this);
passengerComponent = PassengerComponent(this);
}
public void seat() {
passengerComponent.seat();
}
}
Wrap up
I really hope there are not syntax errors.
The power of this approach is that we do not replicate the logic of a Driver or of a Passenger because we write this code only once inside the related component.
The Component approach also allow us to easily create (and maintain) even combination of entity (like Driver, Passenger) and behaviour (DriverInterface, PassengerInterface) simply combining the related component.
It's the best alternative to multiple inheritance not supported by Java and it way better and clearer.

Similar to dasblinkenlight's answer, but I think more technically correct:
interface Person{}
interface Pet{}
interface HumanPassenger extends Person{}
interface PetPassenger extends Pet{}
interface Driver extends HumanPassenger{}
In this case Driver extends HumanPassenger and Person through HumanPassenger's ancestors. You can also do this explicitly via:
interface Driver extends HumanPassenger, Person{}
The reason that I say this is more technically correct is through the "is-a" relationship that descendant classes should have. For example, a HumanPassenger is a Person, a Person is not a HumanPassenger (a person could be anything that a person could be, not just a human passenger) in dasblinkenlight's answer, a person is a passenger, but what if a person is a pedestrian...
EDIT:
Human Passenger, PetPassenger, and Driver, could all also be classes, I was just keeping it simple. example of Driver class:
class Driver extends HumanPassenger implements Person{}
or if HumanPassenger was an interface still:
class Driver implements HumanPassenger{}
or
class Driver implements HumanPassenger, Person{}
All would achieve the same things, though only the classes would be capable of instantiation of course.

Related

Object is more then 1 child, now what?

I have an abstract class called Person.
A person has multiple child classes e.g. Driver, Sorter, Manager.
Each of which has its unique methods, and the ones shared e.g. name/age/location, etc and so I then thought that an abstract parent-class would be the solution. (Person)
Yet now I face a new problem, What if a person is both?
Now I have an 'Object' which is a Driver but also a Sorter.
So when he/she calls in sick, Person has a method called reportSick()
But when object driver.reportSick() is being called, there is a chance that there is another object for the same Person that is a Sorter.
It looks strange to me to have 2 objects for the same thing (The person in this case)
What am I overlooking/doing wrong/misunderstanding?
You can go this way:
Make the interface(or abstract class if needed) Profession and implement your classes (Driver, Sorter, Manager) from it.
Make Person not abstract and add there field List<Profession>. And when you need some methods call it in cycle for each Profession.
You've discovered one of the fundamental limitations of inheritance: It creates a very tight coupling between parent and child. "A Sorter is a Person". Not "A Sorter is some other kind of Person", but literally "A Sorter is directly an extension of Person and nothing else".
You can use composition to make explicit who to call next in the "inheritance" chain.
public interface Person {
public void reportSick();
}
public class OrdinaryPerson implements Person {
public void reportSick() {
// An "ordinary" person does nothing when they report sick.
}
}
public class Driver implements Person {
private Person next;
public Driver(Person next) {
this.next = next;
}
public void reportSick() {
// Driver specific stuff goes here ...
this.next.reportSick();
}
}
// Then do the same for Sorter and Manager ...
Now, if a person is "just" a driver, you can represent them as
new Driver(new OrdinaryPerson())
This person is both a driver and an ordinary person (OrdinaryPerson is our null object; it has no actual behaviors to speak of, so we can use it to break our chain).
If a person is both a driver and a sorter, we can write
new Driver(new Sorter(new OrdinaryPerson()))
and assuming Driver and Sorter each call the inner reportSick method, they'll both get called when you call the method on this aggregate we've constructed.
Driver, Manager & Sorter are just special kind of service that any person is efficient with. It may be one or more.
So, best way to declare interfaces for them and declare method for each without body.
Now declare class which extends abstract class & implements one or more interfaces.
public abstract class Person {
private String name;
private int age;
private String location;
// Constructor (Must)
public Person(String name, int age, String location) {
this.name=name;
this.age=age;
this.location=location;
}
}
public interface Driver {
void isDriving(String name, int age, String location);
}
public interface Sorter {
void isSorting(String name, int age, String location);
}
public interface Manager {
void isManaging(String name, int age, String location);
}
public class Person1 extends Person implements Driver, Manager {
/*
Properties, Constructors & Getters/Setters
*/
#overrides
public void isDriving(String name, int age, String location) {
// Driving Function Body
}
#overrides
public void isManaging(String name, int age, String location) {
// Managing Function Body
}
}

Prevent certain objects from being added to a ArrayList

I was reading Eric Lippert blog about Wizards and Warriors. Interesting read, but I found certain parts hard to understand (not the authors fault, I'm only a beginner in OOP).
He presents the problem of two character types within a game, a Wizard and a Warrior, and the rules are:
A warrior can only use a sword.
A wizard can only use a staff
In the blog, he uses a getter/setter in the first part to handle the weapon for the character, but let's change it to an inventory system. So, we have an abstract class called Player with a list of items(ArrayList).
interface Weapon {
attack(Enemy enemy);
}
public class Staff implements Weapon {}
public abstract class Player {
private List<Weapon> weaponInventory;
//left out constructor and other methods to keep it on point
abstract void add(Weapon add)
}
and use it like so:
public class Wizard extends Player {
#Override
public void add(Weapon add){
//code to add weapon;
}
}
How would you structure the add method to enforce the rule that a Wizard can only use a staff? I thought of calling getClass() or getType() on weapon but those are considered bad practice.
The best answer I could come up with was have a String variable called type, and a getter in the Weapon interface. During object construction, set the type to sword or staff. However, this doesn't really help, as you could create a sword object, pass in staff as the type, and use it.
How would you prevent a sword from being added to the wizards inventory?
How would you structure the add method to enforce the rule that a Wizard can only use a staff?
Either you didn't read the whole series, or you didn't understand its central message. The entire point of that series of articles is to express that there is no good way to structure a method that enforces a restriction on the relationship between subclasses.
This is simply a fact about subclass-based OOP; there are some things it does not model well, and this is one of them. A fundamental principle of many OOP type systems, including that of Java and C#, is Liskov's: that you can always use an instance of a subclass where an instance of a superclass is needed. That makes modeling restrictions in the type system difficult.
In the last part of the series I give the best solution that I know of: model the rules of the simulation as objects themselves, and have a rule enforcer class that gives the user feedback when they attempt to violate a rule. Don't make the type system try to solve your business problems.
You could use something like the following. Note: in the Player class, the weapons can be of any type. However each sub-class of player has its own specific add(). So while this approach enforces the required rules, it loses a little generality.
public class Staff implements Weapon {}
public class Sword implements Weapon {}
public abstract class Player {
private List<Weapon> weaponInventory;
protected final void addWeapon(Weapon weapon) {
weaponInventory.add(weapon)
}
}
public class Wizard extends Player {
public void add(Staff staff) {
addWeapon(staff);
}
}
public class Warrior extends Player {
public void add(Sword sword) {
addWeapon(sword);
}
}
You could use generics:
Weapon and Staff classes remain the same:
public interface Weapon {
void attack(Enemy enemy);
}
public class Staff implements Weapon {
#Override
public void attack(Enemy enemy) {
//Do ur attacking. :)
}
}
The Player class has a generic type:
import java.util.ArrayList;
import java.util.List;
public abstract class Player<T extends Weapon> {
protected List<T> weaponInventory = new ArrayList<>();//Made protected so Wizard can access it.
public abstract void add(T weapon);
}
And the Wizard class extends Player<Staff> (NOT just Player):
public class Wizard extends Player<Staff> {
#Override
public void add(Staff weapon) {
// Add the staff to the list declared in Player
weaponInventory.add(weapon);
}
}
Explanation:
The T in Player<T> is the type of weapon that you want the player to use.
When you extend Player<Staff> in the Wizard class, you're saying that you want Wizard to be a Player that only uses Staffs. This way, the Wizard's weaponInventory list will contain only Staffs.
When you add the Warrior class, it would extend Player<Sword>, which would make its weaponInventory only take Swords.
By the way, I instantiated weaponInventory in the above code and implemented the add method in Wizard.

Using composition as a workaround for inheritance in realm (android)?

In my app, I am using realm as a database platform. Realm has been great thus far- super easy to use, make queries, etc.-though, I have two qualms with it that I am trying to work around.
1) Realm does not support inheritance in model object classes which extend RealmObject.
- I am wondering if any developers out there have used composition as a workaround to the inheritance issue and if its worked for them.
- In other words, say I have a class "car" which extends RealmObject and then I have other classes such as "honda", "toyota", etc. Does it make sense to make separate car objects for each of these which contain either a honda, toyota, etc.?
2) Realm only supports getters and setters in model object classes
- My current workaround for this is by creating static methods within the model object classes.
- In other words, say I want to modify a honda's color, I would call something such as, Honda.updateColor(honda, blue).
- ^ Is this sloppy, or is this essentially the only way to handle such methods.
Really any feedback would be great!
A workaround I've used (in a nutshell)
Composition + Interface inheritance would allow you to get some polymorphism benefits back to your realmObjects.
Some code demonstration
interface IPerson {
String getName();
}
class Person extends RealmObject implements IPerson {
String name;
#Override
public String getName() {
return name;
}
}
interface IWorker extends IPerson {
int getSalary();
}
class Worker extends RealmObject implements IWorker {
Person person;
int salary;
#Override
public String getName() {
return person.getName();
}
#Override
public int getSalary() {
return salary;
}
}
Note
PrimaryKeys unfortunately have to be duplicated.
Check this answer of mine to get more details about this workaround.

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 ) ; }
}

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