多态和接口

1、多态

多态的前提是继承和方法重写。

多态是父类对象表现多种子类的形态的能力的特征。多态就是父类引用子类对象,向同一个父类的不同子类发送同一条消息,行为不同。

使用多态的原因:实现程序设计的开-闭原则,对扩展开放,对修改关闭。

实现多态:

  1. 继承:子类继承父类
  2. 重写:子类方法重写父类方法
  3. 向上转型:父类引用指向子类对象
  4. 调用父类被重写的方法时,不同的子类效果不同。
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 返回值 方法名();

抽象类的特点

  1. 抽象类不能创建实例对象,抽象类的关键字是abstract;
  2. 抽象类可以定义抽象方法,也可以没有抽象方法;
  3. 有抽象方法的类一定要定义成抽象类;
  4. 抽象类中可以定义实例方法;
  5. 抽象类中可以定义构造方法,在子类中可以调用抽象类的构造方法;
  6. 子类继承抽象类,一定要重写抽象方法,如果没有实现父类的抽象方法,则子类也要变成抽象类;
  7. 抽象方法需要在方法前写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. 接口中的方法不能直接使用,必须有一个实现类来实现接口
  2. 接口的实现类必须(覆盖重写)实现接口中的所有抽象方法
  3. 创建实现类的对象,进行方法调用

接口中包含的内容:

1)常量

接口中的常量使用public static final 三个关键字修饰

public static final AGE = 10;

2)抽象方法

接口中的抽象方法必须是两个固定的关键字修饰 public abstract。这两个关键字可以省略不写。

3)默认方法

default  增强接口的通用能力

default  返回值 方法名(){}

4)静态方法

提供通用实现,只能通过接口名调用,不能通过实现类调用

static 返回值 方法名(){}

接口的特点:

  1. 接口不能被实例化,不能有构造方法
  2. 接口中的方法都是抽象方法,jdk1.8之后可以有默认方法和静态方法
  3. 接口中的成员变量是用public static final 修饰的,并且变量名需要大写
  4. 实现类实现接口必须实现接口中的所有方法
  5. 多实现:一个类可以实现多个接口
  6. 接口可以继承接口 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、向上转型
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值