接着昨天没有学完的知识点,继续总结:
1、super关键字的三种用法—用来访问父类的内容
【a】在子类的成员方法中,访问父类的成员变量
【b】在子类的成员方法中,访问父类的成员方法
【c】在子类的构造方法中,访问父类的构造方法
public class Fu{
int num = 30;
public Fu(){}//父类的构造方法
public void method(){//父类的成员方法
System.out.println("父类的方法");
}
}
public class Zi extends Fu{
int num = 20;
public Zi(){
super();//默认,子类的构造方法正在访问父类的构造,super()方法需要位于该语句的第一条
}
public void methodZi(){
System.out.println(super.num);//super.成员变量,来访问父类的成员变量
}
public void method(){
super.method();//通过super.来访问父类的成员方法
System.out.println("子类的方法");
}
}
2.this关键字的三种用法----》用来访问本类内容的
【a】在本类的成员方法中,访问本类的成员变量
【b】在本类的成员方法中,访问本类的另一个成员方法
【c】在本类的构造方法中,访问本类的另一个构造方法
public class Fu{
int num = 30;
public Fu(){}
public void method(){
System.out.println("父类的方法");
}
}
public class Zi extends Fu{
int num = 20;
public Zi(){
super();//将不在赠送
this();//错误写法,调用自己
this(23);//本类的无参构造,访问本类的有参构造,构造方法的重载调用
}
public Zi(int n ){
this.Zi();//访问本类的无参构造方法
}
public void methodZi(){
int num = 10;
System.out.println(num);//访问的是成员方法中的局部变量
System.out.println(this.num);//访问的是本类中的成员变量
System.out.println(super.num);//super.成员变量,来访问父类的成员变量
}
public void methodA(){
super.method();//通过super.来访问父类的成员方法
System.out.println("AAA");
}
public void methodB(){
methodA();//可以直接调用
this.methodA();//用this关键字,强调是来源本类当中
super.method();//通过super.来访问父类的成员方法
System.out.println("BBB");
}
}
3、Java语言是【单继承的】的:一个类的直接父类只能有唯一的一个;但是【可以多级继承】
:向上继承–》java.lang.Object
一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类,可以有很多个兄弟姐妹
【子类就是一个父类,属于继承关系】
4、抽象方法abstract–》非常重要
抽象方法:需要指定到一个具体方法来实现具体的功能----》对父类方法进行覆盖重写
例:计算图形的面积和动物吃东西—》图形和动物都是抽象的定义,什么样的图形和什么动物?我们不明确,这样的都是抽象的;
【特别注意】如果父类当中的方法【不确定如何进行方法的实现】,那么这就应该是一个【抽象方法】
【1】抽象方法和抽象类的格式:
抽象方法:就是【加上abstract关键字,然后去掉大括号】,直接 分号结束;
抽象类:抽象方法所在的类,必须是抽象类才行,在class之前
写上abstract即可;
public abstract class Animal{//使用abstract修饰变成抽象类,因为抽象方法所在的类,必须是抽象类
public abstract void eat();//抽象方法
public void method(){}//普通的成员方法
}
抽象类可以定义普通的方法,但是非抽象类可以不定义抽象方法;—》抽象方法所在的类必须是抽象类,但是抽象类不一定要有抽象方法;
【2】如何使用抽象类和抽象方法
1、不能直接new抽象类对象
【a】Animal animal = new Animal();//错误写法
【b】Cat cat = new Cat();//创建一个子类对象----正确
【c】Animal cat = new Cat();//向上转型----正确
【d】Cat cat = new Animal();//向下转型----正确
2、必须使用一个子类继承一个父类
public class Cat extends Animal(){}
3、子类必须覆盖重写父类当中的所有的抽象方法;
格式:
【a】public abstract void eat();//父类的抽象方法,去掉abstract关键字,补上大括号
【b】public void eat(){}//子类对父类的抽象方法进行覆盖重写
覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号;
4、创建子类对象进行使用;
【a】Cat cat = new Cat();//创建一个子类对象
【b】Animal cat = new Cat();//向上转型
【c】Cat cat = new Animal();//向下转型
一个抽象类不一定含有抽象方法,但是抽象方法所在的类,一定是抽象类
【扩展】public abstract class DemoAbstract{}
//这样没有抽象方法的抽象类,也不能直接创建对象,在一些特殊场景下有用途
————》设计模式————适配器
public abstract class Dog extends Animal{子类也是一个抽象类
public void eat(){};
//public abstract void sleep();//如果没有完全覆盖重写父类当中的所有抽象方法,那么子类必须也是一个抽象类才可以–》子类会默认继承父类的抽象方法,即使不写,抽象也是存在的
}
5、接口就是一个公共的规范标准【产生通用】,接口就是多个类的公共规范,接口是一种引用数据类型;
【非常重点】:接口最重要的内容就是-----》抽象方法
【1】接口定义的格式
【a】类定义的格式
public class 类名称{}
【b】接口定义的格式
public interface 接口名称{}
【2】在类中编译生成.class字节码文件,在interface关键字,编译生成的字节码同样也是.class字节码文件
【注意】接口可以定义【常量】、【抽象方法】、【默认方法】、【静态方法】和【私有方法】
【3】在Java任何版本中,接口都能定义抽象方法
格式:
public abstract 返回值类型 方法名称(参数列表);
public interface InterAbs{
[public abstract ]void method1();
public void method2();
abstract void method3();
void method4();
//public abstract 两个修饰符可以选择性的省略或者不写
【4】接口的抽象方法的使用
【a】接口不能直接使用【不能直接new接口使用】所以不能有构造方法,必须有一个【实现类】来实现该口
接口名 接口 = new 接口名();—错误写法
格式:
public class 实现类名称 implements 接口名称 {
//…
}
【b】接口的【实现类必须覆盖重写接口中所有的抽象】方法:去掉abstract关键字,加上方法体大括号
【c】创建实现类的对象,进行使用;
public class MyImpl implement MyInterfaceAbstract{
//实现类覆盖重写接口所有的抽象方法
public void methodAbs1(){
System.out.println("A");
}
public void methodAbs2(){
System.out.println("B");
}
}
public class DemoInterface{
public static void main(String[]args){
MyInterfaceAbstract inter = new MyInterfaceAbstract();
//错误写法,接口不能直接new接口对象使用
//创建实现类
MyImpl impl = new MyImpl();
impl.methodAbs1();
}
}
【注意】如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己必须是抽象类,因为没有完全覆盖重写,实现类也会继承过来父类的抽象方法,抽象方法所在的类必须是抽象类
6、接口定义默认方法
格式:
public default 返回值类型 方法名称(参数列表){
方法体;
}
【注意】:接口当中的默认方法,可以解决接口升级问题
【1】默认方法的使用:
//接口当中的一个抽象方法
public abstract void methodAbs1();
//接口当中新添加了一个抽想方法,因为实现类没有覆盖重写所有的接口抽象方法,
//实现类会报错
public abstract void methodAbs2();
//将新添加的抽象方法,改成默认方法
public default void methodDefault(){
System.out.println("这是一个默认方法");
}
默认会被实现类继承的
public class Demo01{
public static void main(String[]args){
//创建一个实现类对象
InterfaceA a = new InterfaceA();
a.methodAbs1();//调用抽象方法,实际运行的是右侧的实现类
//调用继承或实现接口,用的谁就调用谁
a.methodDefault();
}
}
【接口默认方法,可以通过接口实现类对象,直接调用;也可以被接口实现类进行覆盖重写;】
7、接口中静态方法的定义:
public static 返回值类型 方法名称(参数列表){
方法体;
}
//就是将abstract或者default换成atatic即可
调用就是【接口名称.静态方法();】----》之前的是 —类名称.静态方法();
【a】接口当中静态方法的使用:
public static void methodStatic(){
System.out.println(“这是一个静态方法”);
}
//impl.methodStatic();错误写法,不可以通过实现类的对象来调用静态方法
不能通过【接口实现类的对象】来调用接口当中的静态方法,通过接口名称直接调用其中的静态方法;
格式:
接口名称.静态方法名(参数);
//直接通过接口名称调用静态方法
//MyInterfaceStatic.methodStatic();正确写法
8、当接口需要抽取一个公共方法,用来解决接口两个默认方法之间的重复代码的问题;但是这个共有方法,不应该让实现类来使用,那就应该使用私有化的private修饰符;
从java9开始,接口当中允许定义私有方法,解决多个接口方法之间重复代码的问题;
【1】普通私有方法,解决多个默认方法之间重复代码的问题
格式:
private 返回值类型 方法名称(参数列表){
方法体
}
2、静态私有方法,解决多个静态方法之间重复代码的问题
格式:
private static 返回值类型 方法名称(参数列表){
方法体
}
9、常量的定义和使用
【接口当中定义“成员变量”,但是必须使用public static final关键字进行修饰的】
从效果上看,这其实就是接口的【常量】
格式:
public static final 数据类型 常量名称 = 数据值;
public interface InterfaceConst{
public static final int num = 10;
//这其实就是一个常量,一旦赋值,就不可以修改
//在接口中定义常量,前面的三个修饰符是可以省略的 int num = 10;
}
【注意】
【a】一旦使用final关键字进行修饰,说明不可改变;
【b】接口当中的常量,必须进行赋值,不能不赋值;必须手动进行赋值,因为不赋值,系统默认值为0,默认之后就不可以改变了;
【c】用final修饰的变量,必须使用完全大写形式NUM ,多个单词要用下划线进行分隔NUM_COUNT
【d】使用直接通过接口名称.常量名
10、在Java9+中,接口的内容可以有:
【1】成员变量其实是常量
public static final 数据类型 常量名称 = 赋值;//不赋值默认为0
【a】常量一定要进行赋值,而且一旦赋值不能进行改变,常量名称完全大写,多个单词使用下划线进行分隔
【b】三个关键字可以省略public static final
【2】接口中最重要的就是抽象方法,
public abstract 返回值类型 方法名称(参数列表);
【a】public abstract 是可以省略的
【b】实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类
【3】从Java8开始,接口里允许定义默认方法
public default 返回值类型 方法名称(参数列表){方法体}
【a】public是可以省略的,default关键字不可省略
【b】默认方法也可以被覆盖重写,如果没有进行覆盖重写,就使用接口里的方法,如果重写就使用实现类的方法
【4】从Java8开始,接口里允许定义静态方法
public static 返回值类型 方法名称(参数列表){方法体}
【注意】接口的静态方法应该通过**【接口名称】进行调用**,不能通过【实现类对象】调用接口静态方法
【5】接口里允许定义私有方法
【a】普通私有方法:private 返回值类型 方法名称(参数列表){方法体}—>解决默认方法中重复代码的问题
【b】静态私有方法:private static 返回类型 方法名称(参数列表){方法体}—>解决静态方法中重复代码的问题
【注意】private的方法只有接口自己才能调用,不能被实现类或别人使用
11、使用接口时注意:
【1】接口是没有静态代码块或者构造方法的,不可以直接new接口对象,通过接口的实现类进行创建对象
【2】一个类的直接父类是唯一的,但是一个类可以同时实现多个接口
public class MyIn implements InterfaceA,InterfaceB{}
//实现多个接口就要覆盖重写所有抽象方法,如果完全覆盖重写,那么该实现类必须是抽象类
【4】如果实现类实现多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可
【5】如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类
【6】如果实现类或实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的方法覆盖重写
【7】一个类的直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类中的方法,继承是优先于接口实现的
【总结】
1、类与类之间是单继承的,直接父类只有一个;
2、类与接口之间是多实现的,一个类可以实现多个接口
3、接口与接口之间是多继承的
【注意】:
1、多个父类接口的抽象方法如果重复,不会报错,因为抽象方法没有方法体
2、多个父类接口的默认方法如果重复,那么子类接口必须进行默认方法的覆盖重写,【而且必须带着default关键字】
今天状态还是不好,感觉学的不踏实,需要调整,敲代码,共勉!!!以马内利