1、多态
多态的前提是继承和方法重写。
多态是父类对象表现多种子类的形态的能力的特征。多态就是父类引用子类对象,向同一个父类的不同子类发送同一条消息,行为不同。
使用多态的原因:实现程序设计的开-闭原则,对扩展开放,对修改关闭。
实现多态:
- 继承:子类继承父类
- 重写:子类方法重写父类方法
- 向上转型:父类引用指向子类对象
- 调用父类被重写的方法时,不同的子类效果不同。
public class Pet {
protected String name;
protected String color;
public Pet(String name, String color) {
this.name = name;
this.color = color;
}
public void eat(){
System.out.println("吃东西");
}
}
public class Cat extends Pet{
public Cat(String name, String color) {
super(name, color);
}
@Override
public void eat() {
System.out.println(this.color+"的"+this.name+"吃小鱼");
}
}
public class Dog extends Pet{
public Dog(String name, String color) {
super(name, color);
}
@Override
public void eat() {
System.out.println(this.color+"的"+this.name+"吃骨头");
}
}
public class Master {
public void feed(Pet pet){
System.out.println("主人喂宠物");
pet.eat();
}
}
public class Test {
public static void main(String[] args) {
Pet cat = new Cat("白色","小白");
Pet dog = new Dog("黑色","小黑");
Master master = new Master();
master.feed(cat);
master.feed(dog);
}
}
2、向上转型/向下转型
向上转型:父类引用子类对象(自动成立,缺点是失去调用子类独有方法的能力)
向下转型:子类引用父类对象(强制转换,慎重),需要使用instanceof进行类型判断
public class Master {
public void feed(Pet pet){
System.out.println("主人喂宠物");
pet.eat();
}
}
public class Test {
public static void main(String[] args) {
Pet p1 = new Cat("多多","白色");
Pet p2 = new Dog("皮皮","黑色");
Master master = new Master();
master.feed(p1);
master.feed(p2);
if (p1 instanceof Cat){
Cat cat = (Cat) p1;
System.out.println(cat.name+"是一只可爱的小猫咪");
cat.catchMouse();
}
if (p2 instanceof Dog){
Dog dog = (Dog) p2;
System.out.println(dog.name+"是一只可爱的小狗狗");
dog.lookkDoor();
}
}
}
3、抽象类
抽象类的关键字:abstract
抽象类一般作为顶层类(父类),被子类继承。
抽象类的定义:[访问修饰符] abstract class 类名{}
抽象方法(没有方法体,也没有{}):[访问修饰符] abstract 返回值 方法名();
抽象类的特点:
- 抽象类不能创建实例对象,抽象类的关键字是abstract;
- 抽象类可以定义抽象方法,也可以没有抽象方法;
- 有抽象方法的类一定要定义成抽象类;
- 抽象类中可以定义实例方法;
- 抽象类中可以定义构造方法,在子类中可以调用抽象类的构造方法;
- 子类继承抽象类,一定要重写抽象方法,如果没有实现父类的抽象方法,则子类也要变成抽象类;
- 抽象方法需要在方法前写abstract关键字,并且不能有方法体和{}。
//定义抽象类,包含抽象方法的类必须是抽象类
public abstract class Pet {
protected String name;
protected String color;
public Pet(String name, String color) {
this.name = name;
this.color = color;
}
//定义抽象方法,不能有方法体和{}
public abstract void eat();
}
public class Cat extends Pet{
public Cat(String name, String color) {
super(name, color);
}
//子类必须重写抽象类的抽象方法
@Override
public void eat() {
System.out.println(this.name+"吃小鱼");
}
public void catchMouse(){
System.out.println(this.name+"抓老鼠");
}
}
public class Dog extends Pet{
public Dog(String name, String color) {
super(name, color);
}
@Override
public void eat() {
System.out.println(this.name+"吃骨头");
}
public void lookDoor(){
System.out.println(this.name+"会看家");
}
}
public class Test {
public static void main(String[] args) {
Pet p1 = new Cat("多多","白色");
Pet p2 = new Dog("嘟嘟","黑色");
p1.eat();
p2.eat();
if (p1 instanceof Cat){
Cat cat = (Cat) p1;
cat.catchMouse();
}
if (p2 instanceof Dog){
Dog dog = (Dog) p2;
dog.lookDoor();
}
}
}
4、接口
接口是一种标准、规范;
对行为(方法)的抽象(与抽象类对比,抽象类具有特征和行为,而接口只关注行为);
是一系列抽象方法的集合;
定制规则,展现多态;
接口和抽象类的地位等同,作为顶级存在(父类);
实现接口意味着拥有了接口所表示的能力。
接口关键字:interface
实现接口:implements
接口的定义格式:
[权限修饰符] interface 接口名{}
接口的使用步骤:
- 接口中的方法不能直接使用,必须有一个实现类来实现接口
- 接口的实现类必须(覆盖重写)实现接口中的所有抽象方法
- 创建实现类的对象,进行方法调用
接口中包含的内容:
1)常量
接口中的常量使用public static final 三个关键字修饰
public static final AGE = 10;
2)抽象方法
接口中的抽象方法必须是两个固定的关键字修饰 public abstract。这两个关键字可以省略不写。
3)默认方法
default 增强接口的通用能力
default 返回值 方法名(){}
4)静态方法
提供通用实现,只能通过接口名调用,不能通过实现类调用
static 返回值 方法名(){}
接口的特点:
- 接口不能被实例化,不能有构造方法
- 接口中的方法都是抽象方法,jdk1.8之后可以有默认方法和静态方法
- 接口中的成员变量是用public static final 修饰的,并且变量名需要大写
- 实现类实现接口必须实现接口中的所有方法
- 多实现:一个类可以实现多个接口
- 接口可以继承接口 A extends B
//接口
public interface Irun {
public abstract void run();
}
//接口实现类
public class Falali implements Irun{
@Override
public void run() {
System.out.println("法拉利在路上行驶....");
}
}
public class Baoma implements Irun{
@Override
public void run() {
System.out.println("宝马在路上行驶....");
}
}
public class Test {
public static void main(String[] args) {
Irun r1 = new Falali();
Irun r2 = new Baoma();
r1.run();
r2.run();
}
}
5、接口和抽象类的区别
应用场景:抽象类是对事物属性和行为的抽象,符合is a 的关系
接口是对行为的抽象,实现接口,拥有相应的功能
相同点:都是顶级的父类存在的
6、抽象类和接口的对比
7、面向对象的三大特征
特征 | 定义 | 实现 |
---|---|---|
封装 | 隐藏实现细节,提供公共的访问接口 | 将属性私有化,提供公共的访问接口 |
继承 | 从一个类中派生出一个新的子类,子类拥有父类中非私有的成员 | 子类extends父类 |
多态 | 父类的同一个方法在不同的子类中会有不同的实现 | 1、继承 2、重写 3、向上转型 |