面向对象(接口与多态)


接口

接口基本概述及格式

接口概述

接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量,构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法、默认方法和静态方法、私有方法

接口定义格式

接口用关键字interface修饰

public interface 接口名{}

接口的使用

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

public class 类名 implements 接口名 {}

注意:接口的实现类必须重写接口中所有的抽象方法,要么该类是一个抽象类

接口成员的特点

成员变量

只能是常量,默认修饰符:public static final

成员方法

只能是抽象方法,默认修饰符:public abstract

构造方法

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

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

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

  • 默认方法定义格式

    public default 返回值类型  方法的名称(参数列表){
        方法体;
    }
    
  • 默认方法的好处

    实现类可以不用重写默认方法,默认方法可以用于接口升级

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

静态方法:使用static修饰,供接口直接调用。
静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用

  • 静态方法定义格式
    public static 返回值类型 方法名称(参数列表){
        方法体
    }
    

继承父类并实现多个接口

在继承体系中,一个类只能继承一个父类,而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现,并且,一个类能继承一个父类,同时实现多个接口。

多实现格式

class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {    
    // 重写接口中抽象方法【必须】
    // 重写接口中默认方法【不重名时可选】
} 

注意事项

接口中,有多个抽象方法时,实现类必须重写所有的抽象方法。如果抽象方法有重名的,只需要重写一次即可
如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法

接口之间的多继承

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似,接口的继承使用extends关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。
注意:接口多继承之后,如果想使用,我们还必须定义实现类,才能使用

类与类的关系

类与类:
	继承关系,只能单继承,不能多继承,可以多层继承。
		
接口与接口:
	继承关系,可以单继承也可以多继承。public interface Sister extends Father,Mother 
    
类与接口:
	实现关系,可以单实现,也可以多实现。 public class Son extends Object implements Father,Mother
	并且还可以在继承一个类的同时实现多个接口。

抽象类和接口的区别

A:成员区别
	抽象类:
		成员变量:可以变量,也可以常量
		构造方法:有
		抽象类不能实现化
		成员方法:可以抽象,也可以非抽象
	接口:
		成员变量:只可以静态常量  可以省略 public static final
		构造方法:无
		接口不能实例化
		成员方法:可以抽象      可以省略public abstract
				有默认方法
				静态方法
B:关系区别
	类与类
		继承,单继承, 多层继承
	类与接口
		实现,单实现,多实现
	接口与接口
		继承,单继承,多继承

C:设计理念区别
	抽象类【共性功能】。
	接口【扩展功能】。

多态

什么是多态

多态是继封装,继承之后,面向对象的第三大特征。
定义:同一个事物,在不同时刻体现的状态不一样

多态的前提

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

多态格式

  • 普通多态的格式

    父类 对象 = new 子类();
    
  • 抽象类多态的格式

    抽象类 对象名 = new 抽象类子类();
    
  • 接口多态的格式

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

多态中的成员访问特点

成员变量

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

成员方法

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

多态的好处和弊端

多态的弊端

不能使用子类的特有成员

多态的好处

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

多态中的转型

为什么要用转型

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。所以,想要调用子类特有的方法,必须做向下转型。

向上转型

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

// 向上转型
父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();

向下转型

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

// 向下转型
子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c = (Cat) a;

转型的异常

问题描述

转型的过程中,一不小心就会遇到这样的问题

 public class Test {
    public static void main(String[] args) {
        // 向上转型  
        Animal a = new Cat();  
        a.eat();        // 调用的是 Cat 的 eat
        
        // 向下转型 
        Cat c = (Cat)a;
        c.catchMouse();//调用自己的方法
        System.out.println("================");
 
        // 向下转型  
        Dog d = (Dog)a;       //引用的父类,是多态cat类,并不是dog 
        d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】    
    }  
}

这段代码可以通过编译,但是运行时,却报出了ClassCastException类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。

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

instanceof使用格式

变量名 instanceof 数据类型 
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false
public class Test {
    public static void main(String[] args) {
        // 向上转型  
        Animal a = new Cat();  
        a.eat();               // 调用的是 Cat 的 eat

        // 向下转型  
        if (a instanceof Cat){
            Cat c = (Cat)a;       
            c.catchMouse();        // 调用的是 Cat 的 catchMouse        
        } else if (a instanceof Dog){
            Dog d = (Dog)a;       
            d.watchHouse();       // 调用的是 Dog 的 watchHouse
        }
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BoatsZhou

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

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

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

打赏作者

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

抵扣说明:

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

余额充值