文章目录
|
- 小姐姐:多态是什么啊?
- 情圣:多态就像对你的情感,当你不回我消息时,我的心态会异常低沉,翻着聊天记录看是否哪句话说错了;当你给我分享一些琐事时,即使不搞笑我也会伴着你笑,因为你和我分享我就高兴。
- 渣男:我不会为了一时痛快让自己心爱的女人去duotai的,这种不负责任没有道德的事,我保证不会让他发生在你身上的。
- 我:憨批!!!哎,还是我手把手教你吧。
- 友情价:一万元。
- 爱情价:一辈子。
多态
面相对象程序设计的三大支柱是封装、继承、多态。多态作为最后一个,肯定是比较难的。但小姐姐你放心,本流氓一定服务到位,包你会。会了你做我女朋友可好啊~~
首先继承关系是一个子类能继承父类的特征,并附加一些新特征。子类是他的父类的特殊化,每个子类的实例都是其父类的实例,但反过来不成立。
如:我喜欢你,你继承了我的方法,你也喜欢我,你还有一个独特的方法,你喜欢小孩。当然我也喜欢小孩,但我没有喜欢小孩这个方法,我若想喜欢小孩可以调用你的方法,这就是多态。
多态意味着父类型的变量可以引用子类型的对象。
是不是还有点懵逼,不怕,看看下面的几个小概念,弄个例题你就会了。嘿嘿~
动态绑定
方法可以在父类中定义而在子类中重写。方法可以在沿着继承连的多个类中实现。在下面这个代码中:
Object a = new Game;
System.out.println(a.toString);
这里先要了解两个术语:
声明类型
一个变量必须被生命为莫衷类型,变量的这个类型成为他的声明类型。这里a的声明类型是Object。
实际类型
实例可以使用声明类型或的的子类型的构造方法创建,变量的实际类型是被变量引用的对象的实际类。这里a的实际类型是game,因为a引用是使用new Game()创建的对象。
a调用的哪个eoString()方法有a的实际类型决定,这里也就是由Game决定。
工作机制
动态绑定工作机制为:假设对象a是类 c 1 , c 2 , c 3 . . . c n c_1,c_2,c_3...c_n c1,c2,c3...cn的实例,其中 c 1 c_1 c1是 c 2 c_2 c2的子类, c 2 c_2 c2是 c 3 c_3 c3的子类,…。java中 c n c_n cn为Object类,因为java中所有的类都是继承自Object这个类。
如果对象a调用一个方法p,JAM会一次在类 c 1 , c 2 , c 3 . . . c n c_1,c_2,c_3...c_n c1,c2,c3...cn中查找方法p的是想,知道找到为止。一旦找到一个实现,就停止查找,然后调用这个首先找到的实现。
package demo;
public class DynamicBindingDemo {
public static void main(String[] args) {
/* GraduateStudent类继承于学生,但里面没有toString方法,所以会向上找其父类的toString方法
若GraduateStudent中有toString方法,则会首先调用GraduateStudent的toString方法
*/
m(new GraduateStudent());
// Student虽然继承于person,但其本身有toString方法,所以会直接输出
m(new Student());
// Person有toString方法
m(new Person());
// 该类的toString方法,默认情况下返回一个由改对象所属的类名@符号,以及十六进制形式表示的该对那个的内存地址组成的字符串
m(new Object());
}
public static void m(Object x) {
System.out.println(x.toString());
}
}
// 研究生类继承学生
class GraduateStudent extends Student {
}
// 学生继承人
class Student extends Person {
@Override
public String toString() {
return "Student";
}
}
// java中所有的类都是继承自Object这个类
class Person extends Object {
@Override
public String toString() {
return "Person";
}
}
对象转换和Instanceof操作符
当需要使用子类特有功能时,需要进行类型转换
概念:
一个对象的引用可以类型转换为对另一个对象的引用,这就是对象转换。
隐式转换(向上转型、自动类型转换)
上面那个例题中我们用了这个语句
m(new Student())
这个语句是将对象new Student()赋值给一个Object类型的参数。这条语句等价于
Object a = new Student();
m(a)
由于Student的实例也是Object的实例,所以,语句Object a = new Student();
是合法的,这就是隐式转换。也称为向下转换:
// 子类型转换成父类型
父类 对象名 = new 子类();
显式转换( 向下转型、强制类型转换)
因为Student对象总是Object的实例,但Object的对象不一定是就是Student。如大香蕉一定是水果,但水果不一定是大香蕉。
所以如果我们想把对象引用a复制给Student类型的对象,不能直接Student b = a
,必须用该Student b = (Object)a;
才行.
instanceof关键字的用法:
只能在继承层次内进行转换,否则可能造成异常( ClassCastException ) 将父类对象转换成子类之前,使用instanceof 进行检查
意思是判断前边的对象是否是后边的数据类型.
对象名 instanceof 数据类型
实例如下:
Animal an = new Dog;
//判断当前对象是否是Dog类的对象,如果是,再调用watch()方法.
if (an instanceof Dog){//判断an是否是Dog类的对象
//能走到这里,说明条件满足
Dog dog=(Dog)an;
dog.watch;
}
例题:
父类几何类
public class SimpleGeometricObject {
private String color = "white";
private java.util.Date dateCreated;
public SimpleGeometricObject() {
dateCreated = new java.util.Date();
}
public SimpleGeometricObject(String color) {
dateCreated = new java.util.Date();
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public java.util.Date getDateCreated() {
return dateCreated;
}
public String toString() {
return "created on " + dateCreated + "\ncolor: " + color;
}
}
子类:圆类
package zhuanxing;
public class CircleFromSimpleGeometricObject extends SimpleGeometricObject {
private double radius;
public CircleFromSimpleGeometricObject() {
}
public CircleFromSimpleGeometricObject(double radius) {
this.radius = radius;
}
// get 和set方法
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
// 获取面积和直径
public double getArea() {
return radius * radius * Math.PI;
}
public double getDiameter() {
return 2 * radius;
}
}
子类:矩形类
public class RectangleFromSimpleGeometricObject extends SimpleGeometricObject {
private double width;
private double height;
public RectangleFromSimpleGeometricObject() {
}
public RectangleFromSimpleGeometricObject(double width, double height) {
this.width = width;
this.height = height;
}
// get 和 get方法
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
// 求面积
public double getArea() {
return width * height;
}
// 求周长
public double getPerimeter() {
return 2 * (width + height);
}
}
测试类
public class CastingDemo {
public static void main(String[] args) {
// 创建并初始化两个对象
Object object1 = new CircleFromSimpleGeometricObject(1);
Object object2 = new RectangleFromSimpleGeometricObject(1, 1);
// 显示圆和矩形
displayObject(object1);
displayObject(object2);
}
// 显示对象的一种方法
public static void displayObject(Object object) {
if (object instanceof CircleFromSimpleGeometricObject) {
System.out.println("The circle area is " +
((CircleFromSimpleGeometricObject)object).getArea());
System.out.println("The circle diameter is " +
((CircleFromSimpleGeometricObject)object).getDiameter());
}
else if (object instanceof RectangleFromSimpleGeometricObject) {
System.out.println("The rectangle area is " +
((RectangleFromSimpleGeometricObject)object).getArea());
}
}
}