I have a method in a class say
// super class
public class Car{
public void printMe(Car c){
if(c instanceof BMW){
Utility.printString("Bmw");
}else if(em instanceof VOLVO){
Utility.printString("Volvo");
}else if(em instanceof AUDI){
Utility.printString("Audi");
}else {
Utility.printString("Kia");
}
}
// sub classes
public class Bmw extends Car{
}
public class Volvo extends Car{
}
public class Audi extends Car{
}
public class Kia extends Car{
}
}
Now here i have a different class that loops through a list of Cars and print the correct statement according to the type of the Car
public class AccessCars{
ArrayLists<Car> carsList = listOfcars();
for(Car car: carsList){
car.PrintMe(car);
}
}
In the loop above i call the printMe(Car c) method on car en give car as an argument. Is is legal to do that? And if not, what is the best way of doing it?
thanks for your answer
a better way will be:
public abstract class Car {
public abstract void printMe();
}
public class Audi {
#Override
public void printMe() {
Utility.printString("Audi");
}
this is the OOP way to do it - using polymorphism
note that Car is implicit argument for printMe()
I would advise against polymorphism in this case -- every class prints out a string in the same way. The behavior is constant -- only the value printed varies. As such, the correct approach (IMO) is a variable that's printed out by printMe, and each derived class just initializes the variable appropriately.
It's legal, but not very good design. Perhaps a better approach is to define an abstract method Car.getModel() and implement it in each subclass to return the appropriate value. After all, you don't want to have to change the code for Car every time you add a new subclass.
Um, you can do that ... but I think you're missing the point of inheritance and overriding methods:
public class Car{
void printMe()
{
System.out.println("I'm a Car!");
}
}
public class Audi extends Car{
void printMe()
{
System.out.println("I'm an Audi!");
}
}
for(Car car: carsList){
car.PrintMe()
}
You get the overriden methods. Each car will print its name.
That being said, this is a silly example just to show how that works.
You'd really declare the Car class abstract and have printMe() be abstract, unless you had some reason to ever instantiate Car directly.
It's generally not acceptable to do this; since you already have "specialized" classes, why not put the printMe method in these classes? In case you want to enforce the subclasses have their own version of printMe, just make the printMe method in the super-class as abstract.
On a side note, another thing you might be interested would be a Visitor pattern:
In object-oriented programming and
software engineering, the visitor
design pattern is a way of separating
an algorithm from an object structure
it operates on. A practical result of
this separation is the ability to add
new operations to existing object
structures without modifying those
structures. It is one way to easily
follow the open/closed principle.
Definetly not OK, to do it.
I would define an abstract method called .Print() on the super class in such a way every subclass of Car must override it, and have your own way of Printing. Just like many samples above!
It is legal, however, not best of practice.
instanceof is a heavy operation on runtime environment and as such should be avoided if possible. This is not needed here, as every Car instance do the same thing - print itself. Consider this example:
public class Car {
// do some great stuff here...
public abstract String printMe();
}
public class Audi extends Car {
// do some great stuff here...
public String printMe() {
return "Audi rocks!";
}
}
// same for the other car models...
now iterate on the Car collection and run printMe for each.
Related
i'm beginner and just learning abstract classes and interfaces but really struggeling to get it right.
MY Class structure.
Abstract Class Vehicle
Class Car (extends Vehicle, implements ITuning)
Class Motorcycle (extending Vehicle)
Interface ITuning
I want to have an abstract method doRace() that I can use in my Car class to compare the Car Objects (car.getHp()) and prints the winner. I try to implement a doRace(object o) into the Interface ITuning and a doRace(Car o) into my Car class but get the error. How can I implement that correctly ?
The type Car must implement the inherited abstract method
ITuning.doRace(Object)
But if do chage it to Object, i can't use it in my Car class…
public interface ITuning
{
abstract void doRace(Object o1);
}
public Car extends Vehicle implements ITuning
{
public void doRace(Car o1){
if(this.getHp() > o1.getHp())
};
}
Any Idea what i'm doing wrong? I assume its a comprehension error
You can make ITuning generic.
public interface ITuning<T> {
void doRace(T other);
}
Implementation will be like this:
public class Car extends Vehicle implements ITuning<Car> {
#Override
public void doRace(Car other) {
//do comparison
}
}
Implementation in other classes will be quite similar, just change the generic parameter.
As a side note, i would rename the interface to something more fitting. Considering that tuning a vehicle is the act of modifying it to optimise its' performance, ITuning providing functionality to do the actual racing is counter intuitive.
You can change your ITuning interface to
public interface ITuning
{
void doRace(Vehicle other);
}
Since Vehicle defines the getHp() method this ensures that your actual implementation can access it.
The difference to Chaosfire's answer is that this will allow you to do a race between different types of vehicles, e.g. a Car and a Motorcycle, while the generic ITuning<T> class will be limited to races between equal types*.
Chaosfire's point regarding the interface name is still valid.
*This is a bit over-simplified to make my point clearer. Of course Car could implement ITuning<Car> and ITuning<Motorcycle> but this may not be what you want.
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 ) ; }
}
What is the advantage of writing:
Bicycle bike = new RoadBike(...);
instead of
RoadBike bike = new RoadBike(...);
Assuming RoadBike extends Bicycle of course.
I ask because even if I write
RoadBike bike = new RoadBike(...);
I can still use all the methods in Bicycle because of the extension, so what is the point of writing it the other way?
Thanks!
If Bicycle were an interface, it would allow you to just pass around that interface and make your methods more "generic" or "polymorphic".
If you had another class, StreetBike,(and it implemented the Bicycle Interface) you could use that class and RoadBike to say call method 'ride' and each class would ride differently based on the implementation.
Public Interface Bicycle {
public ride();
}
public StreetBike implements Bicycle{
public ride(){
System.out.println("I am riding on the street");
}
}
public RoadBike implements Bicycle{
public ride(){
System.out.println("I am riding on the road");
}
}
Taking it a step further we can use this SIMPLE example, but I think it gets the point across
//PERSON POJO
public Person {
//properties
public rideBike(Bicycle bike){
bike.ride(); //could be StreetBike or RoadBike, depends on what you pass in. That's the power of it.
}
}
The clearest way to express polymorphism is via an abstract base class (or interface)
public abstract class Bicycle
{
...
public abstract void ride();
}
This class is abstract because the ride() method is not defined for Bicycle. It will be defined for the subclasses RoadBike and MountainBike. Also, Bicycle is an abstract concept . It’s got to be one or the other.
So we defer the implementation by using the abstract class.
public class RoadBike extends Bicycle
{
...
#Override
public void ride()
{
System.out.println("RoadBike");
}
}
and
public class MountainBike extends Bicycle
{
...
#Override
public void ride()
{
System.out.println("MountainBike");
}
}
Now we can difference by calling Bicycle at runtime base class Bicycle but due to run time binding respective subclass methods will be invoked .
public static void main(String args)
{
ArrayList<Bicycle> group = new ArrayList<Bicycle>();
group.add(new RoadBike());
group.add(new MountainBike());
// ... add more...
// tell the class to take a pee break
for (Bicycle bicycle : group) bicycle.ride();
}
Running this would yield:
RoadBike
MountainBike
...
Hope this will clear you what the difference is !
The advantage is that Bicycle reference is more general and can refer to any object which has Bicycle in its inheritance hierarchy for example MountainBike. It offers more flexibility and does not binds you to concrete implementation. This is one of the basic principles in OOP. That said, there are some cases, like when used in short method when using Bicycle or RoadBikemakes no difference. Also there is the aspect of invoking overloaded methods which is determined by reference type at compile time (depending on the reference type, different method might be called even thought they point to the same object) but having those kinds of overlaoded methods is not advised.
You might get better explanation here.
I have two classes
public class ABC {
public void test() {
Car a = new Car();
a.start();
}
}
public class DEF {
public void test() {
Car a = new Car();
a.start();
a.stop();
}
}
Now both these classes do pretty much the same thing, how can extract out the commonality, or what is the best way.. would a template method work.. where by i use an interface... and have one parent method that calls an abstract method that is implemented on the subclasses?... but that would mean that one class has a no operation in a method?
Yes you can use template method pattern here:
public abstract class Template {
public void test() {
Car a = new Car();
a.start();
if(shouldStop()) {
a.stop();
}
}
public abstract boolean shouldStop();
}
public class ABC extends Template {
public boolean shouldStop() {
return false;
}
}
public class DEF extends Template {
public boolean shouldStop() {
return true;
}
}
Here you are adding a hook to allow subclasses to stop if they wish. You can obviously extends this to include any other optional functionality.
I kind of depends on what else you have beyond this trivial example, but you could do something like this:
public class ABC {
public Car test() {
Car a = new Car();
a.start();
return a;
}
}
public class DEF extends ABC {
public Car test() {
Car a = super.test();
a.stop();
}
}
The template method is usefull when you have steps that should be shared for all subclasses.
Template Method Wiki
The basic structure is what you already said. An abstract class with some abstract methods which have to be implemented by subclasses.
Interfaces, in the other hand, defines an API, not a behavior. So it's useless in this case.
Okay, so you've got commonalities in the methods:
Car a = new Car();
a.start();
What you can do, is make an abstract class, that both of these classes extend.
public abstract class ParentClass
{
public void test()
{
Car a = new Car();
a.start();
}
}
Then from your subclasses, you can call: super.test();. This will call the method in the parent class, before returning to the current method and finishing off the subclass implementation.
Advantages of this method
Any common code in these classes can now be pulled out, and placed inside the ParentClass. This means no repetition of code, which is always good. It also means that your class has logical structure, provided the superclass functions appropriately. This, again, is considered good practice because it makes your code more semantically logical.
Disadvantages of this method
The ParentClass is the ONLY class that the other classes can extend. This is called Inheritance and multiple Inheritance is something that Java does not support, so keep this in mind. If your ABC also shared similar functionality with another set of classes, then you might want to re-think your class structure.
Generally, and as much as possible, I prefer to put common functionalities in external (and static) methods, mainly for two reasons (they are very slightly different and related):
I prefer avoiding to keep my "inheritance slot", I can inherit from just one class and I want to be greed in extending, using it when very necessary or in the appropriate case (see point 2);
Inheritance should be used only where there's a relation of "type of" between classes; anyway, I personally believe that in Java you could be coerced, in some cases, to use inheritance in a wrong way because the Java language doesn't offer a mechanism for sharing common functionalities (such as modules in ruby).
This isn't exactly the definition of implicit type conversion, but I'm curious how many standards I'm breaking with this one...
I'm creating an abstract class in Java that basically casts its variables depending on a string passed into the constructor.
For example:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
You see what I'm getting at? Now the problem I run into is that my compiler wants me to explicitly cast that into Test1 or Test2 in the doSomething method - which I understand, as the compiler won't assume that it's a certain object type even though the if statements pretty much guarantee the type.
I guess what I'm getting at is, is this a valid solution?
I have other classes that all basically do the same thing but use two different libraries depending on a simple difference and figure this class can help me easily track and make changes to all of those other objects.
You are right. This is a horrible way to achieve polymorphism in design. Have you considered using a factory? A strategy object? It sounds like what you are trying to achieve can be implemented in a more loosely-coupled way using a combination of these patterns (and perhaps others).
For the polymorphism of doSomething, for example:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
Of course, you need to unify the behaviors of Test1 and Test2 (and other concrete Thing classes, present and planned) under a set of common interface(s).
PS: This design is commonly known as Strategy Pattern.
I would create a separate class file. So you would have something like this:
1. You abstract "MyClass"
->within "MyClass" define an abstract method call doSomething...this will force the specific implementation of the method to it's subclasses.
2. Test1 would be the implementation of MyClass which would contain the implementation of the doSomething method
3. Create a utility class that does the check "instanceOf" that check should not be in the constructor it belongs in another class.
So in the end you would have 3 class files an Abstract Class, Implementation of the Abstract and a Class that does the "instanceOf" check. I know this sounds like a lot but it's the proper way to design, for what I think you are attempting to do. You should pick up a design patterns book, I think it would help you a lot with questions like these.
The Open-Closed principle would be better satisfied by moving the object creation outside of this class.
Consider changing the constructor to accept an object that implements an interface.
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
This makes it possible to change the behavior of the class (open to extension) without modifying its code (closed to modification).
The better way to do this is to create an interface which will specify a set of methods that can be guaranteed to be called on the object.
Here's an example:
public interface TestInterface
{
void doTest();
}
Now you can write your classes to implement this interface. This means that you need to provide a full definition for all methods in the interface, in this case doTest().
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
Looks really boring and pointless, right? Lots of extra work, I hear you say.
The true value comes in the calling code...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
No if statements, no instanceof, no ugly blocks, nothing. That's all moved to the class definitions, in the common interface method(s) (again, here that is doTest()).