接口、多态

第一章 接口

1.1 接口的概念

1.概念:
    对外暴露的规则/规范/标准,只要符合该规则/规范/标准的东西都可以使用
2.接口,是Java语言中一种引用类型,编译后也有对应的class文件,是方法的汇总

3.作用: 实现对类的功能的扩展,解决java中类的单继承的局限性

1.2 接口中可以定义的内容

1.抽象方法【jdk7及以前】: public abstract 返回值类型 方法名称(参数列表...); 没有方法体{}
2.默认方法【jdk8及以后】: public default 返回值类型 方法名称(参数列表...){...} 有方法体{}
3.静态方法【jdk8及以后】: public static 返回值类型 方法名称(参数列表...){...} 有方法体{}
4.常量【jdk7及以前】:public static final 数据类型 变量名称 = 数据值; 不可以修改其值
注意:
    接口在设计之初只是为了制定一套规则/规范/标准,所以接口设计之初内部只能定义抽象方法

1.3 接口的定义格式

类的定义格式
    修饰符 class 类名 {
        //成员变量
        //常量
        //成员方法
        //构造方法
        //静态方法    
    }
    
接口的定义格式
    public interface 接口名称 {
        //常量
        //抽象方法
        //默认方法
        //静态方法
    }

1.4 接口中抽象方法的定义格式和使用

1.接口中抽象方法的定义格式
    public abstract 返回值类型 方法名称(形式参数列表...);
    注意:
        (1)和以前定义方法格式相同,但是需要去掉{},添加abstract
        (2)返回值类型和参数列表根据需求确定
        (3)接口中抽象方法,有默认修饰符public abstract,不写也有
            抽象类中抽象方法必须写public abstract,不能省略
            
2.接口中抽象方法的使用
    (1)不能直接创建接口的对象
    (2)定义实现类 实现 接口 关键字 implements
       格式:
            public class 类名 implements 接口A,接口B {
                //覆盖重写接口中的所有的抽象方法
            }
    (3)实现类中覆盖重写接口中的所有的抽象方法
        去掉abstract关键字,添加{}
        快捷键: ctrl + i
    (4)创建实现类对象
    (5)使用实现类对象调用方法

//定义接口
public interface MyInter01 {
    //抽象方法
    public abstract void method();
    void show();
}
//定义实现类MyInter01Impl 实现 接口MyInter01
public class MyInter01Impl implements MyInter01{
    @Override
    public void method() {
        System.out.println("MyInter01Impl...method...");
    }

    @Override
    public void show() {
        System.out.println("MyInter01Impl...show...");
    }
}
//接口中抽象方法的定义格式和使用
public class Demo01Interface {
    public static void main(String[] args) {
        //错误: 接口不能直接new对象
        //MyInter01 mi01 = new MyInter01();

        //创建实现类对象
        MyInter01Impl mi01 = new MyInter01Impl();

        //使用实现类对象调用方法
        mi01.method();
        mi01.show();

    }
}

 1.5 接口中默认方法的定义格式和使用

接口中默认方法的定义格式和使用
    问题:
        定义接口后,有很多实现类在使用接口,如果对接口功能升级添加了新的抽象方法
        导致所有的实现类必须修改代码,太麻烦

    解决方案: 默认方法

    默认方法的定义格式:
        public default 返回值类型 方法名称(形式参数列表...){
            //方法体;
        }

    默认方法的使用:
        1.不能使用接口名称调用默认方法
        2.不能使用实现类名称调用默认方法
        3.只能使用实现类对象调用默认方法

    注意:
        1.接口中的默认方法,不强制要求实现类进行覆盖重写
        2.但是实现类可以根据需求,选择性的覆盖重写接口中的默认方法
        3.如果实现类覆盖重写接口中的默认方法,必须去掉default关键字

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

1.定义格式
    public static 返回值类型 方法名称(形式参数列表...) {
        方法体;
   }

2.使用格式
    (1)只能使用接口名称调用接口中的静态方法
    (2)不能使用实现类名称调用接口中的静态方法
    (3)不能使用实现类对象调用接口中的静态方法

3.注意:
    (1)接口中的静态方法,属于接口本身,与实现类无关,在实现类中不存在覆盖重写
    (2)类中的静态方法,属于类本身,与接口无关,与对象无关
    (3)类中的静态方法:
         名直接调用 ---推荐使用
         对象直接调用 ---不推荐使用

总结: 静态的内容要么用接口名称调用,要么用类名称调用

1.7 接口中成员变量的使用

接口中成员变量的使用
接口中定义的变量,都是常量(值不可以改变)
默认修饰符public static final 不写也有
接口中常量默认值认为是无效的必须显式赋值
接口中的常量的使用: 接口名称.常量名称
建议: 接口中常量的命名全部使用大写字母,单词之间用_分隔 

1.8 接口的多实现

接口的多实现
    在继承体系中,一个类只能继承一个父类【类的单继承: 亲爹只能有一个】。
    对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现【类实现接口的多实现: 干爹可以有多个】。并且,一个类能继承一个父类,同时实现多个接口。
    
一个类能继承一个父类,同时实现多个接口格式:
    public class 子类名 extends 父类名 implements 接口名A,接口名B {
        覆盖重写抽象父类和接口中的所有的抽象方法
    }

注意:
    子类必须重写父类和接口中的所有抽象方法,只要有一个抽象方法没有被重写,该子类必须定义为抽象类,看AbstractZi05类

1.9 多个接口中重名的抽象方法 

多个接口中重名的抽象方法
实现类: 只需要覆盖重写一次

1.10 多个接口中重名的默认方法

多个接口中重名的默认方法
实现类,必须覆盖重写一次,而且要去掉default关键字

1.11 多个接口中重名的静态方法

多个接口中重名的静态方法
接口中静态方法属于接口本身,和实现类无关
只能使用接口名称调用

  多个接口中重名的静态方法
    接口中的静态方法属于接口本身,与实现类无关
    只能用接口名称调用
    所以多个接口中重名的静态方法之间互不影响,
    直接使用对应的接口名调用接口

1.12 抽象类和接口的区别

抽象类和接口的区别
1.内容上的区别?
    抽象类:    成员变量,常量,构造方法,成员方法,静态方法
    接口:     常量,默认方法,静态方法

2.本质上的区别:
    抽象类: 本质是一个类,就是对某种事物的描述
        整个继承体系中的共性内容

    接口:     是用来制定规则/规范/标准的,只要符合规则/规范/标准都可以用
        扩展继承体系中的类的功能的

1.14 没有抽象方法的抽象类存在意义

抽象类中可以没有抽象方法,存在的意义是什么?
适配器设计模式
    1.接口中定义了相当多的抽象方法
    2.实现类,想实现接口,但是只会用到接口中的某个/某几个方法
        如果实现类 实现接口的 话 ,必然覆盖重写所有的抽象方法    相当麻烦

    3.解决方案:
        根据接口创建一个实现类,所有被重写后的方法的{}中没有任何代码
        对接口进行空实现,因为实现类中的所有方法{}中没有代码,
        所以创建实现类的对象调用方法,没有意义,把该实现类定义为抽象类,
        用户创建抽象类的子类,根据需求重写方法

第二章 多态

2.1 生活中的多态

面向对象的三大特征: 封装,继承,多态
封装: 提高代码的安全性
继承: 提高代码的复用性
多态: 提高代码的扩展性
多态的概念:同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。
简单的理解: 同一个事物,表现出来不同的形态
举个栗子:
    比如说你自己
        在学校中: 是一个学生
        在餐馆中: 是一个顾客
        在公司中: 是一个员工
        在你家里: 是妻子/丈夫
        回老家: 是一个孩子
    比如说H2O:
        在常温下: 是液体
        在高温下: 是水蒸气
        在低温下: 是固体冰
   

2.2 多态中的代码体现

多态中的代码体现
1.概念:
    同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。
    java中的多态: 指的是对象具备多态性
2.举例:
    假设学生Student类是人Person类的子类
    学生 是 一个学生    
    //不是多态 左侧是Student类型,右侧是Student对象,左右一致
    Student stu = new Student();

    学生 是 一个人
    //是多态 左侧是Person类型,右侧是Student对象,左右不一致,左边是父类,右边是子类对象
    Person p = new Student();

3.多态的前提:
    (1)必须要有继承或者接口实现
    (2)必须要有父类引用指向子类对象(父类类型的变量保存子类对象的地址值)
    (3)必须要有方法的覆盖重写,否则将失去多态的意义
    
4.多态的本质
       (1)就是把子类对象当成父类类型使用
           父类引用指向子类对象(父类类型的变量保存子类对象的地址值)

       (2)多态的方式调用方法,方法跟着对象走

2.3 多态的好处和弊端

多态的好处和弊端
不使用多态:
    好处: 可以调用子类的特有行为
    弊端: 扩展性极差
使用多态:
    好处: 扩展性强
    弊端: 不可以调用子类的特有行为

多态的好处:
   可以使用父类/接口,作为方法的参数,提高方法的扩展性
问题:
   下面分别是有Animal的子类Dog和Cat作为方法参数,定义了两个方法
   Animal的子类可以有任意多个,这样定义的方法也就会有任意多个
   每创建一个子类,就得再添加一个方法,太麻烦

   解决方案:
       所有的子类对象,都可以当做父类类型使用
       所以可以使用父类类型作为方法的参数
    类作为方法的参数:
        调用方法时,传递的是该类的对象或者是该类的子类对象

    类的数据体现形式是对象
    抽象类的数据体现形式是子类对象
    接口的数据体现形式是实现类对象
    暴露新的问题: 方法内部不能直接调用子类的特有行为了

2.5 多态中的向上向下转型

多态中的向上转型
        多态的本质(父类引用指向子类对象): 就是向上转型
        类似于 基本类型的自动类型转换
        取值范围小的数据或者变量可以直接赋值给取值范围大的变量

        int a = 100;//int: 占4个字节
        double d = a;//double: 占8个字节

        不需要进行特殊的处理

    多态中的向下转型
        类似于 基本类型的强制类型转换
        取值范围大的数据或者变量不可以直接赋值给取值范围小的变量

        double d2 = 100;//double: 占8个字节
        int c = (int)d2;//int: 占4个字节

        强制类型转换:
            转后类型 对象名称 = (转后类型)转前的对象或者变量名称;
注意:多态的向下转型(强制类型转换)存在安全隐患
        如果转换前的类型和转换后的类型不一致,就会报出类型转换异常(ClassCastException)

2.6 instanceof关键字

强制类型转换(向下转型)存在安全隐患:
如果转后类型和创建对象的具体类型不一致,报出类型转换异常 ClassCastException
如何解决呢?
如果变量a指向的是Dog类型,强制转换成Dog对象
如果变量a指向的是Cat类型,强制转换成Cat对象
如何判断变量a指向的到底是哪种类型的对象呢?

    使用instanceof关键字
    使用格式:
        boolean result = 对象名 instanceof 类名
            如果对象名称中保存的是该类的对象,返回true。
            如果对象名称中保存的不是该类的对象,返回false。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值