- 继承
- 重写
- 父类引用指向子类对象
多态的实现方式
- 重写
- 接口
- 抽象类和抽象方法
注意事项:
《Effective Java》一书中提到,接口优于抽象类
接口和抽象类的区别:
1)抽象类允许包含某些方法的实现,但是接口则不允许;
2)为了实现由抽象类定义的类型,类必须成为抽象类的一个子类,任何一个类,只要它定义了所有必要的方法,并且遵守通用约定,它就被允许实现一个接口。而不管这个类是否处于类层次(class hierarchy)的哪个位置。因为Java只允许单继承,所以抽象类作为类型定义受到了极大的限制。
父类引用指向子类对象
这篇文章的主题在于父类引用指向子类对象,把子类对象直接赋给父类引用叫向上转型(upcasting),向上转型不用强制转型。
向上转型
举个简单例子,
创建父类对象Animal,只有一个成员变量name,
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Animal {
private String name;
}
创建子类对象Dog继承父类对象Animal,多一个成员变量barkingTime
import lombok.\*;
import java.util.Date;
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Data
public class Dog extends Animal {
private Date barkingTime;
@Builder
public Dog(String name, Date barkingTime) {
super(name);
this.barkingTime = barkingTime;
}
}
import com.alibaba.fastjson.JSON;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class UpCastingDemo {
public static void main(String[] args) {
// 从默认时区的系统时钟获取当前的日期时间
LocalDateTime localDateTime = LocalDateTime.now();
// 将此日期时间与时区相结合
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
// 本地时间线LocalDateTime到即时时间线Instant时间戳
Instant instant = zonedDateTime.toInstant();
// UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
Date date = Date.from(instant);
// 父类引用指向子类对象
Animal animal = Dog.builder().name("旺财").barkingTime(date).build();
System.out.println(JSON.toJSONString(animal));
}
}
打印结果如下,
在java内存中,animal父类引用指向堆中生成的Dog对象,从animal父类对象只能获取到name成员变量,但是引用对象实际上是有两个属性值的。
参考链接:
1、https://www.runoob.com/java/java-polymorphism.html
2、http://www.codexy.cn/java/java-polymorphism.html
3、http://c.biancheng.net/java/90/
4、https://www.gitclone.com/gogs/search/clonesearch?q=Effective-Java-3rd-edition-Chinese-English-bilingual