1

Sorry for the confusing title, I am a bit confused myself so I'll just use an example :D Suppose we have:

public abstract class Vehicle {
    public abstract void paint();
}
public class Car extends Vehicle {
    public void paint() {
        ...
    }
    public void sell() {
        ...
    }
}
  1. Type Car
Car c = new Car();
c.paint();
c.sell(); //works
  1. Type Vehicle
Vehicle c = new Car();
c.paint();
c.sell(); //error

So what's the point of using the latter format? I can only think of restriction/privacy but even then can't think of a reasonable example. Which option is better to use as general practice?

Oladipo
  • 1,579
  • 3
  • 17
  • 33
Yoghurt
  • 25
  • 5
  • I can't find a dup on SO, but there's a good question about this on [Software Engineering](https://softwareengineering.stackexchange.com/questions/232359/understanding-programming-to-an-interface). – azurefrog Sep 04 '19 at 18:08
  • Does [this](https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) answer your question? – Sweeper Sep 04 '19 at 18:15
  • Why does your model allow the selling of cars, but not necessarily other types of vehicles? If all vehicles can be sold, you should be saying so in the `Vehicle` class. – arcadeblast77 Sep 04 '19 at 18:30
  • If you added a sell method to your abstract vehicle class, then it would work. Because vehicle has no idea that the sell method exists, it won't. If you cast to type car in your second version before you call sell, then it will work because you have told the jvm what type the object is. This is a fundamental aspect of object-oriented programming. – Richard Barker Sep 04 '19 at 19:45
  • Thanks a lot guys for all your help and direction :)) – Yoghurt Sep 05 '19 at 19:39

4 Answers4

0

I'am not an expert, but as far as i can tell

the later format is used to implement abstraction, i.e you hide the inner working of the function.

the implementation now depends on the class extending your Vehicle class (here Car). This free's you to implement the paint function without worrying which class is implementing it.

eg:

Bike extends Vehicle {
// body
}

now you implement

Vehicle.paint() and depending on your configuration you can paint either bike or car. it's quite powerful if you use it well

also it's good to use interface as it enforce java to use empty methods.

in case you are wondering why the error, it's because Vechicle does not know the function sell exist, as that is defined by class Car and not Vechicle, but paint() will function as if it's running Car.paint().

Akash Jain
  • 684
  • 9
  • 23
0

Super class means you have something in common between some classes, these common things might be properties or method.abstract

class means you have some concept that may need some of its methods implementation done by its subclass.

you may somewhere in your app need vehicle concept regardless of what vehicle it is, paint the vehicle, so, you need just know that passed parameter is a vehicle.

both concepts are right, but it depends on your usage and your designing.

if you need to have only vehicle concept regardless of its subtype, you must use second one, and in this case you need to use method sell() you must use the first one because you made the method available and it's properties came from defining part, not instantiating part.

At the end, study Abstraction in OOP, it may help you more. hope it was helpful :)

Majid
  • 16
  • 1
  • okay, that clears things up for me a bit more... I can see now that disregarding the sub-type might be a wanted feature/property. A company painting vehicles for me shouldn't have the privilege to then sell them... Thanks! – Yoghurt Sep 05 '19 at 19:37
0

The idea of the interface is to have different classes implementing the interface, and the caller does not need to know (or care) which one it is.

As another example, take Java's OutputStream. It's an abstract class (so a bit more "meat" or logic than a real interface), but the main idea is the same. In your program you can write to an OutputStream that the caller passes in. You just take care of writing what you have to write. The caller on the other hand can decide on what needs to be done with the data you write: send it over the network or save it to a file or pipe it into another program? Zip it or encrypt it before doing so? The caller can do that by passing you a different OutputStream, and your code does not need to change to handle network I/O, compression, or encryption.

Tests can pass a ByteArrayOutputStream to capture your program's output.

Robert
  • 7,394
  • 40
  • 45
  • 64
0
Vehicle c = new Car();
c.paint(); // <- THIS is the point of the latter format.

The point of this format is the ability to call paint even when you don't know what type of Vehicle is being painted.

Imagine you had an ArrayList of Vehicles that needed to be painted.

ArrayList<Vehicles> vehicles = new ArrayList<>();

vehicles.add(new Car());
vehicles.add(new Jet());
vehicles.add(new Tank());

for(Vehicle vehicle : vehicles) {
    vehicle.paint(); // <- This is the power, right here.
}

You would certainly not call on the sell method inside of that loop, since it only applies to Cars (according to your design), and not all Vehicles.

arcadeblast77
  • 560
  • 2
  • 12