AP计算机教程9-11:多态
多态(polymorphism)是个大词,可以分解为强调数量丰富的“多”和形态的“态”两部分。所以这个词本质上就是指有许多种形态。在Java中,多态意味着根据object的类型,不同的method会在程序运行时被动态选择调用。
这很像一种小朋友玩的玩具,上面有带有动物名称和图像的转盘以及可以旋转的指针。当指针停下来以后,玩具会发出对应动物的叫声。
在Java程序中的类比是你可以创建class Animal
,带上abstract
的makeNoise
method。每个Animal
的子类都可以重写makeNoise
来发出每种动物自己的叫声。这被称作基于继承的多态。具有共同parent class的child class可以有自己独有的特性。
Java中的每个object都有声明类型(或编译时类型)以及实际类型(或运行时类型)。顾名思义,前者在object声明时被决定,而后者则由实际创建object的class来决定。
如下所示的nameList
的声明类型为List
,而实际类型则为ArrayList
。Java编译器会检查声明类型是否拥有或者继承了用到的method,否则在找不到的情况下会报错。interface List
的确有add
method,因而代码可以通过编译。在程序运行时,所执行的add
method则由class ArrayList
来具体提供,因为它是实际类型。如果在child class里找不到方法的实现,则会一直延继承树上溯。
List<String> nameList = new ArrayList<String>(); nameList.add("Hi");
变量message
有Object
的声明类型和String
的实际类型。执行message.indexOf("h");
时会报错,因为indexOf()
并非Object
的method。
Object message = new String("hi"); message.indexOf("h");
任何对象变量都可以存放声明类型或者声明类型的child class所实例化的object。但是在用()
强制转换对象类型前,仅能调用声明类型本身拥有的method。
0:00
What is the output from running the main method in the Shape class?
public class Shape { public void what() { System.out.print("Shape");} public static void main(String[] args) { Shape[] shapes = {new Shape(), new Rectangle(), new Square(), new Circle()}; for (Shape s : shapes) { s.what(); System.out.print(" "); } } } class Rectangle extends Shape { public void what() { System.out.print("Rectangle"); } } class Square extends Rectangle { } class Oval extends Shape { public void what() { System.out.print("Oval"); } } class Circle extends Oval { public void what() { System.out.print("Circle");} }
Sqaure
直接继承了Rectangle
,并没有重写what
method。What is the output from running the main method in the GradStudent
class?
public class Student { public String getFood() { return "Pizza"; } public String getInfo() { return this.getFood(); } public static void main(String[] args) { Student s1 = new GradStudent(); s1.getInfo(); } } class GradStudent extends Student { public String getFood() { return "Taco"; } }
getInfo()
中调用的getFood()
是GradStudent
中的。What is the output from running the main method in the RaceCar
class?
public class Car { private int fuel; public Car() { fuel = 0; } public Car(int g) { fuel = g; } public void addFuel() { fuel++; } public void display() { System.out.print(fuel + " "); } public static void main(String[] args) { Car car = new Car(5); Car fastCar = new RaceCar(5); car.display(); car.addFuel(); car.display(); fastCar.display(); fastCar.addFuel(); fastCar.display(); } } class RaceCar extends Car { public RaceCar(int g) { super(2*g); } }
RaceCar
重写了构造函数,让初始燃料变成了原来的两倍。Given the following class definitions and a declaration of Book b = new Dictionary();
which of the following will cause a compile-time error?
public class Book { public String getISBN() { // implementation not shown } // constructors, fields, and other methods not shown } public class Dictionary extends Book { public String getDefinition(String word) { // implementation not shown } }
Book
中没有getDefintion()
method,因而b
不能直接调用它。Assume that the following declaration appears in a client program Base b = new Derived();
. What is the result of the call b.methodOne()
?
public class Base { public void methodOne() { System.out.print("A"); methodTwo(); } public void methodTwo() { System.out.print("B"); } public static void main(String[] args) { Base b = new Derived(); b.methodOne(); } } class Derived extends Base { public void methodOne() { super.methodOne(); System.out.print("C"); } public void methodTwo() { super.methodTwo(); System.out.print("D"); } }
super.methodOne()
中调用的methodTwo()
会是Derived
中定义的。
0 条评论