- super
- this
- 接口
- 三大特征---多态
- 引用类型转换
super和this的含义
- super: 代表父类的存储空间标识(可以理解为父类的引用)
- this: 代表当前对象的引用(谁调用就代表谁)
super和this的用法:
super
- 访问父类的成员变量
- 访问父类的成员方法
- 访问父类的构造方法
super.成员变量;
super.成员方法;
super(形参列表);//访问父类的构造方法
在继承关系中,父类的构造方法访问特点:
- 子类构造方法中有一个默认的隐式的super()调用,所以一定是先调用父类的构造,后执行的子类构造
- 子类构造可以通过super关键字来调用父类的重载构造
- super的父类构造必须是子类构造方法的第一条语句,,不能一个子类构造调用多次super构造
总结: 子类必须调用父类的构造方法,不写会赠送一个super();写了则用写的指定super(),super只能用一次,必须在第一条语句
this
- 访问当前类的成员变量
- 访问当前类的成员方法
- 访问当前类的构造方法
this.成员变量
this.成员方法
this(形参列表);//访问当前类构造方法
- this()构造方法在调用时,不能形成闭环.
- this()在调用时必须是构造方法的第一条语句,也是唯一一个
- super()和this()两种构造方法调用时,不能同时使用
继承的特点
- java语言只支持单继承,不支持多继承
- java语言只支持多级继承(继承体系)
- 顶层父类是Object类,所有的类默认都继承Object类
- 子类和父类是一种相对的概念(Object除外)
抽象类
概述: 父类当中的方法, 被他的子类们重写,子类的各自实现又不一样,那么父类的方法声明和方法体只有声明还有意义,而方法体内容则没有存在的意义,我们把这种没有方法体内容的方法叫做抽象方法. Java语法规定,如果一个类包含抽象方法,则该类是一个抽象类.
定义 :
抽象方法: 没有方法体的方法
抽象类: 包含抽象方法的类
abstract关键字格式
抽象方法: 使用abstract关键字修饰成员方法,该方法就成了一个抽象方法,抽象方法只包含了一个方法名,没有方法体
修饰符 abstract 返回值类型 方法名(参数列表);
示例:
public abstract void run();
抽象类: 如果一个类包含了抽象方法,那么该类就是一个抽象类
修饰符 abstract class ClassName{ }
示例:public abstract void Animal{
public abstract void run();
}
抽象的使用
继承抽象类的子类必须重写父类所有的抽象方法,否则,该子类也必须声明为一个抽象类.
如何使用抽象类和抽象方法:
- 不能直接创建new抽象类对象
- 必须用一个子类来继承抽象父类
- 子类必须重写抽象父类的全部抽象方法
- 重写实现, 子类重写父类中的抽象,必须去掉抽象方法中的abstract关键字,然后添加方法体{ }
- 创建子类对象进行使用
- 抽象类也有构造方法,否则无法被继承
- 方法重写,是子类对父类的抽象方法的完全实现,我们将这种方法重写操作,也叫做 %实现方法%
注意事项
- 抽象类不能创建对象,如果创建对象,则会编译失败,只能创建其非抽象子类的对象
- 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的
- 抽象类不一定包含抽象方法,但是有抽象方法的类必定是抽象类
- 抽线类的子类,必须重写父类中所有的抽象方法,否则编译无法通过,除非该子类也是抽象类
学习目标
- 写出定义接口的格式
- 实现接口的格式
- 说出接口中成员的特点
- 说出多态的前提条件
- 理解多态的向上转型 ;向下转型
- 使用多态和接口完成相应的案例开发
接口
概述: 接口是Java语言中一种引用类型 , 是方法的集合 , 如果说类的内部封装了成员变量 成员方法和构造方法 , 那么接口的内部主要就是 '封装了方法' ,包含了抽象方法(JDK1.7及以前) ; 默认方法和静态方法(JDK1.8), 私有方法(JDK1.9)
接口的定义:与类的定义很相似 , 但是使用interface关键字,它也会被编译成.class文件.但它不是类,而是另外一种引用数据类型
接口的使用,不能直接创建对象,但是可以被实现(implements关键字,类似于继承,又不是继承),一个实现接口的类,可以看做接口的子类,需要重写接口中所有的抽象方法,创建该类对象,就可以调用方法了
public class 实现类名称 implements 接口名称{
//抽象方法
//默认方法
//常量
//静态方法
//私有方法(JDK1.9)
}
含有抽象方法
抽象方法:使用abstract修饰,没有方法体内容,该方法主要供子类使用
public interface InterfaceName{
public abstract void method();
//public abstract 可以省略不写
}
含有默认方法和静态方法
默认方法:使用default关键字修饰,不可省略,供子类调用或子类重写
静态方法:使用static关键字修饰的方法,供接口直接调用
public interface InterfaceName{
public default void method(){
//方法体内容
}
}
含有私有方法和私有静态方法
私有方法: 使用private 关键字,供接口中的默认方法或者静态方法调用.
public interface InterfaceName{
private void method(){
//方法体内容
}
}
基本实现
实现概述: 类与接口的关系为一种实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类 ,实现的动作相似于继承,格式相仿,只不过关键字不同,实现 implements关键字
非抽象类实现接口:
1.必须重写接口中所有的抽象方法
2,继承了接口当中的默认方法,既可以直接调用 又可以重写
public class 实现类 implements 接口名称{
//重写接口当中的所有抽象方法
//重写接口当中的默认方法 [可选]
}
抽象方法的使用: 必须全部实现
默认方法的使用: 可以继承使用也可以重写 ,但是只能通过实现类的对象来调用
继承默认方法:
public interface Biological{
public default void fly(){
System.out.println("天上飞");
}
}
//实现类
public class Animal implements Biological{
//继承 什么都不写 直接调用
}
//测试类
public class InterfaceDemo02{
public static void main(String []args){
Animal animal = new Animal();
animal.fly();
}
}
重写默认方法:
public interface Biological{
public default void fly(){
System.out.println("天上飞");
}
}
//实现类
public class Animal implements Biological{
//重写
@Override
public default void fly(){
System.out.println("天上飞,飞的很开心");
}
}
//测试类
public class InterfaceDemo02{
public static void main(String []args){
Animal animal = new Animal();
animal.fly();
}
}
静态方法的使用: 静态的一般都和类.class文件相关,只能使用接口名来调用 , 不可以通过实现类的类名或实现类的对象来调用
私有方法的使用:
-
私有方法只有默认方法可以调用 ,
-
私有静态方法默认方法和静态方法可以调用
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有的方法中,供默认方法去调用. 从设计的角度考虑,私有的方法是对默认的方法和静态的方法的一种辅助
//定义一个接口
public interface Biological{
private void run1(){
System.out.println("跑起来.....");
}
public default void funMethod1(){
//System.out.println("跑起来.....");
run1();
}
public default void funMethod2(){
//System.out.println("跑起来.....");
run1(); //调用私有方法
}
}
接口的多实现
在继承体系中,一个类只能直接继承一个父类,对于接口来说,一个类可以实现多个接口,叫做接口的多实现. 而且,一个类能直接继承一个父类的同时可以实现多个接口
public class ClassName extends 父类 implements 接口1,接口2,...{
//重写接口中所有的抽象方法
//重写接口中的默认方法[可选]
}
父类和接口中抽象方法重名问题
由于抽象方法没有方法体,没有实际意义,对程序没有影响,子类重写 一次 即可
默认方法重名问题
接口中,有多个默认方法时,实现类都可以继承使用,如果默认方法有重名的,必须重写一次.不重写会报错(接口冲突)
public interface A{
public default void methodA(){}
public default void methodB(){}
}
public interface B{
public default void method(){}
public default void methodB(){}
}
//定义实现类 不重名可以选择不重写 重名的 必须重写一次
public class C implements A,B{
@Override
public void methodB(){
System.out.println("methodB被重写");
}
}
静态方法重名问题
接口中,如果存在同名的静态方法并不存在冲突,原因是只能通过各自的接口名访问静态方法,子类无法调用.
优先级的问题
当一个类,即继承了一个父类,又同时实现了多个接口,父类中的成员方法与接口中的默认方法重名时. 子类就近选择执行父类的成员方法(类优先原则)
public interface A{
public default void methodA{
System.out.println("AAAAAA");
}
}
//定义父类
public class B{
public void methodA{
System.out.println("BBBBB");
}
}
//子类
public class E extends B implements A{
//未重写methodA()方法
}
//定义测试类
public class InterfaceDemo06{
public static void main(String[] args){
E e = new E();
e.methodA(); ////////输出BBBBBBBB
}
}
接口的多继承 [ 了解 ]
一个接口能继承另一个或者多个接口,这和类之间的继承比较相似. 接口的继承也使用extends关键字,子接口继承父接口的方法,如果父接口中的默认方法有重名现象,那么子接口需要重写一次
public interface A{
public default void method{
System.out.println("AAAAAA");
}
}
public interface B{
public default void method{
System.out.println("BBBBBB);
}
}
//定义子接口
public interface C extends A,B{
@Override
public default void method(){
System.out.println("CCCCCCC);
}
}
备注: 子接口重写默认方法, default 必须保留.
其他成员特点 :
- 接口中,无法定义成员变量,但是可以定义常量,因为值不可变 , 默认使用 public static final(可以省略)
- 接口中,没有构造方法
- 接口之中,没有静态代码块 (因为没有类变量可被初始化)
接口的优点:
- 定义规则
- 降低耦合性 [高内聚 , 低耦合]
- 拓展原有类的功能
接口与抽象类的区别:
相同点:
- 都包含抽象方法,子类都必须重写抽象方法
- 都不能直接实例化对象
- 都位于继承的顶端(父类),用于被其他类实现或继承
区别:
- 抽象类里面可以包含普通成员方法,接口不能包含
- 一个类只能直接继承一个父类( 可以是抽象类),一个类也可以实现多个接口
- 类与类之间只能是单继承关系,接口与接口可以多继承
- 抽象类可以定义普通成员变量和常量 , 接口只能定义常量 public static final修饰