可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am learning java concepts.
I got a doubt in java inheritance concept.
In inheritance we can assign subclass instance to a base class reference
and with that we can access only base class function.
and we can assign any subclass instance in the hierarchy of inheritance to base class reference.For an type of instance assigning to a particular base class reference we can access only base class functions and i didn't find any difference.
Can any one give me actual concept
why we have to assign subclass instances to base class references?
what is the need to do that?
Instead we can access those base class functions from subclass reference only know.
Explain by considering a particular base class and many subclasses in the hierarchy.
回答1:
The reason why you may want to do this is to create more robust designs. Take for example the Collections Framework in Java. You have a List interface and then you have two implementations, ArrayList and LinkedList.
You can write your program to use a LinkedList specifically or an ArrayList specifically. However, your program then depends on those specific implementations.
If you write your program to depend on the super type, List, instead then your program can work for either of the List implementations. Lets say you want to write a method that does something to a List and you wrote this:
public void doSomething(ArrayList a){}
This method can only be called with an ArrayList, not a LinkedList. Suppose that you wanted to do the same thing with a LinkedList? Do you then duplicate your code? No.
public void doSomething(List l){}
Will be able to accept either type of List.
The principle behind this is program to an interface not an implementation. That is, List defines the functions of ALL lists.
There are many many examples of this usage.
回答2:
Inheritance and Polymorphism are cornerstones of object-oriented programming and serve a few different purposes, in short:
- Code reuse by extending a base class with specific functionality,
- Interface design by providing an abstract set of functionality, which where different implementations are tailored to different requirements and
- Encapsulation by hiding specific functionality, which isn't needed in certain contexts
among others.
The last point also highlights, why one might use a restricted set of functionality, even in a case the actual implementation provides more than that. Take for example the Collection interface. By using this interface, we focus on methods like isEmpty
, contains
or size
but not the actual implementation.
回答3:
What you've described is the essence of polymorphism. It's a word from the Greek that means "many forms".
If I gave you a simple hierarchy like this, you can see how the test code can get different calculation implementations out of each object without concerning itself about what kind of Shape it was dealing with:
public interface Shape
{
double calculateArea();
}
class Circle implements Shape
{
private double radius;
Circle(double r) { this.radius = r; }
public double calculateArea() { return Math.PI*radius*radius; }
}
class Square implements Shape
{
private double side;
Square(double s) { this.side = s; }
public double calculateArea() { return side*side; }
}
// This would be a separate JUnit or TestNG annotated test.
public class ShapeTest
{
@Test
public void testCalculateArea()
{
Map<Shape, Double> expected = new HashMap<Shape, Double>()
{{
put(new Circle(1.0), Math.PI);
put(new Square(1.0), 1.0);
}};
for (Shape shape : expected.keySet())
{
Assert.assertEquals(expected.get(shape), shape.calculateArea());
}
}
}
回答4:
Polymorphism.
I am a method that gives you a List<String>
. All you need to know about the thing I've actually given you is that it's a list and has the behaviour and semantics of a list, i.e. you can put things in it, it'll maintain their ordering, and you can iterate over it.
What you don't need to know is how I'm storing things, how I'm making them accessible, etc. That's not important. For all you care, it could be a LinkedList<String>
, an ArrayList<String>
or something entirely new. Suffice it to say, I've picked something, and you can happily use it.
You're absolutely right that when you're using inheritance to extend classes and add new behaviour, then you need to reference the subclass to be able to access it. The two approaches are somewhat complimentary, but different, use cases.
回答5:
Let us say Vehicle is the base class and Car and Plane are subclasses. Let us say Vehicle has has a method move().
Car overrides this by going on road. Plane overrides this by flying.
Why move() should be part of Vehicle base class?
Because any Vehicle can move(). But we can't implement move() in Vehicle because all vehicles doesn't move the same way i.e. there is no common behavior. We still want this in the base class so that we can have polymorphic behavior i.e. we can write code like below. As you can see there is only one method called runVehicle(...) that can work on any Vehicle class.
void runVehicle(Vehicle v)
{
v.move();
}
Car c=new Car();
runVehicle(c);
Plane p=new Plane();
runPlane(p);
回答6:
There is no real need to do that, except when the API demands it. For example, if in a particular API or code library there is a
void ReallyUsefulFunction(BaseClass instance)
that you would like to use, you can derive a class fom BaseClass and implement its methods in the SubClass. Then you can now pass the subclass to the function.
Still, technically, you could implement your own
void MyReallyUsefulFunction(MyClass instance)
which imitates the same functionality. But like what MYYM had explained, the benefits of code reuse etc. can be huge, and that is when you will want to take advantage of polymorphism.