day08_JAVAOOP(三)

接口

概述

接口是Java语言中一种引用类型,是方法的集合,接口内部主要就是封装了方法(功能),包含抽象方法(JDK7及以前)、默认方法和静态方法(JDK8)、私有方法(JDK9

总结

  1. 接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用
  2. Java中的接口更多的体现在对行为的抽象
  3. 应用场景:为了功能拓展

接口定义格式

接口用关键字interface修饰

格式:public interface 接口名{}

接口的使用

接口是不能创建对象,必须有实现类才能使用,类实现接口用implements表示

格式:public class 类名 implements 接口名{}

  • :接口的实现类必须重写接口中所有的抽象方法,除非该类是抽象类

接口成员的特点

成员变量

只能是常量,默认修饰符:public static final(可省略)

成员方法

只能是抽象方法,默认修饰符:public abstract(可省略)

构造方法

(因为接口主要是扩展功能的,而没有具体存在)

接口默认方法的定义和使用

  • 默认方法:使用default修饰,不可省略,供子类调用或重写

  • 定义格式:

  public default 返回值类型 方法名(参数列表){
      //方法体
  }
  • 好处:接口的默认方法,实现类可以不用重写,默认方法可用于接口升级(往写好的项目代码中进行扩展,在接口中加默认方法对其他类没有影响,代码维护性好)

接口静态方法的定义和使用

  • 静态方法:使用static修饰,供接口直接调用
  • 静态方法只能使用接口名调用,不能通过实现类的类名或对象调用
  • 定义格式:
public static 返回值类型 方法名称(参数列表){
    //方法体
}

代码演示

  • 接口
package cn.zhuo_01;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 10:30
 * @Desc: 接口
 */
public interface Inter {

    //接口成员变量——只能是常量,不能更改的
    int num =10;//此处省略了默认修饰符public static final
    //默认修饰符:public static final(可省略)
    public static final int num1 = 20;
    public  int num2 = 30;
    static int num3 = 40;
    final int num4 = 50;
    static final int num5 = 60;

    //构造方法——无
    // public Inter() {}

    //接口成员方法,默认修饰符:public abstract可以省略
    void show();//接口成员方法只能是抽象方法
    //接口中不能有方法主体
    // public void show() {}

    //接口默认方法
    public default void method(){
        System.out.println("默认方法,default修饰不能省略");
    }

    //接口静态方法
    public static void show1(){
        System.out.println("接口静态方法,使用static修饰");
    }
}

  • 实现类
package cn.zhuo_01;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 10:31
 * @Desc: 实现类
 */
public class InterImpl implements Inter{

    //实现类必须对接口中的抽象方法进行重写
    @Override
    public void show() {

        //TODO 功能待优化
        System.out.println("对接口中的抽象方法进行重写");
    }

    //接口中的默认方法,不用重写,也可以手动重写
    @Override
    public void method() {
        System.out.println("接口中的默认方法,可以选择是否重写,也可以根据实际需求进行重写");
    }

    //实现类中无法重写静态方法
}

  • 测试类
package cn.zhuo_01;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 11:28
 * @Desc: 测试类
 */
public class Test {
    public static void main(String[] args) {
        //创建实现类对象
        InterImpl inter = new InterImpl();

        //调用方法
        inter.show();

        //调用默认方法
        inter.method();

        //调用静态方法
        //静态与.class文件相关,接口的静态方法只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
        Inter.show1();
    }
}

多态

什么是多态

同一个事物,在不同时刻体现的状态不一样

多态的前提

  • 要有继承或实现关系
  • 要有方法的重写
  • 要有父类引用指向子类对象(Father f = new Son;

多态格式

普通类多态的格式

父类 对象名 = new 子类();

抽象类多态的格式

抽象类 对象名 = new 抽象类子类();

接口多态的格式

接口 对象名 = new 接口实现类();

多态中的成员访问特点

成员变量

编译看左边(父类),运行看左边(父类)

成员方法

编译看左边(父类),运行看右边(子类)

代码演示

  • 父类
package cn.zhuo_02;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:17
 * @Desc: 父类
 */
public abstract class Animal {
    //成员变量
    int age = 40;

    //成员方法
    public abstract void eat();
}

  • 子类
package cn.zhuo_02;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:17
 * @Desc: 子类
 *          多态的前提:
 *              1. 继承或实现关系
 *              2. 要有方法重写
 *              3. 要有父类引用指向子类对象   fu  f = new zi();
 */
public class Cat extends Animal{

    //成员变量
    int age = 20;
    //子类独有的成员变量
    int weight = 10;

    //父类成员方法重写
    @Override
    public void eat() {
        System.out.println("cat吃鱼");

    }

    //子类独有的成员方法
    public void playGame(){
        System.out.println("cat后空翻");
    }
}

  • 测试类
package cn.zhuo_02;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:21
 * @Desc: 测试类
 */
public class Test {
    public static void main(String[] args) {


        //通过多态方法 Fu fu = new Zi();
        //父类引用指向子类对象
        Animal cat = new Cat();

        //多态访问:成员变量
        System.out.println(cat.age);//输出父类的age=40
        // 【父new子】——>成员变量:编译看左边(父类) 运行看左边(父类)
        //System.out.println(cat.weight);——>弊端:多态不能使用子类特有的成员

        //多态访问:成员方法
        cat.eat();
        //【父new子】——>成员方法:编译看左边(父类) 运行看右边(子类)
        //cat.playGame();——>弊端:多态不能使用子类特有的成员
    }
}

多态的好处和弊端

多态的弊端

不能使用子类特有的成员

多态的好处

提高程序的扩展性,定义方法的时候,使用父类型作为参数,在使用时,使用具体的子类型参与操作

代码演示

  • 父类
package cn.zhuo_03;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:37
 * @Desc: 父类 抽象
 */
public abstract class Animal {
    public abstract void eat();
}
  • 子类
package cn.zhuo_03;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:39
 * @Desc: 子类之一
 */
public class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("cat吃鱼");
    }
}
package cn.zhuo_03;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:38
 * @Desc: 子类之一
 */
public class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("dog吃骨头");
    }
}
  • 测试类
package cn.zhuo_03;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 14:39
 * @Desc: 测试类
 */
public class Test {

    public static void main(String[] args) {

        /*Cat cat = new Cat();
        showCatEat(cat);

        Dog dog = new Dog();
        showDogEat(dog);*/

        Animal cat = new Cat();
        showAnimal(cat);
        //Animal dog = new Dog();
        showAnimal(new Dog());

    }

    /*public static void showCatEat(Cat cat){
        cat.eat();
    }

    public static void showDogEat(Dog dog){
        dog.eat();
    }*/

    public  static void showAnimal(Animal animal){

        animal.eat();
    }
}

多态中的转型

多态的弊端是不能使用子类特有的成员,为了解决这个弊端,必须做向下转型(强转)

向上转型

多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的

  • 使用格式:父类类型 变量名 = new 子类类型();

向下转型

父类类型向子类类型转换的过程,这个过程是强制的

一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型

  • 使用格式:子类类型 变量名 = (子类类型)父类变量名;

转型的异常

  • ClassCastException类型转换异常

instanceof关键字

为了避免ClassCastException异常的发生,Java提供了instanceof关键字,给引用变量做类型的校验

  • 使用格式:
变量名 instanceof 数据类型
//若变量属于该数据类型,返回true
//若变量不属于该数据类型,返回false

代码演示

  • 父类
package cn.zhuo_04;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 15:29
 * @Desc: 父类
 */
public abstract class Animal {

    public abstract void eat();

    public void show(){
        System.out.println("show");
    }
}

  • 子类
package cn.zhuo_04;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 15:30
 * @Desc:
 */
public class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("cat 吃鱼");
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
package cn.zhuo_04;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 15:33
 * @Desc:
 */
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void watchHouse(){
        System.out.println("看家");
    }
}

  • 测试类
package cn.zhuo_04;

/**
 * @Auther: 不学无墅
 * @Date: 2023/7/14 15:33
 * @Desc:
 */
public class Test {

    public static void main(String[] args) {
        //向上转型
        Animal animal = new Cat();
        animal.eat();//调用的是 Cat的 eat()

        //向下转型  zi z = (zi)fu;  向下转型,获取子类特有的方法
        Cat c=(Cat) animal;
        c.eat();//调用子类重写的方法
        c.catchMouse();//调用的是子类独有的方法
        c.show();//调用子类继承的父类的方法

        //Dog d = (Dog) animal;//引用的父类,是多态 cat类,并不是 dog
        //d.watchHouse();//运行报错,调用的是 Dog的 watchHouse

        Animal animal1 = new Dog();

        Dog dog=(Dog) animal1;
        dog.eat();
        dog.watchHouse();


    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

找不到工作当个咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值