继承,覆盖,抽象,接口,子类实例化

    科技2022-07-11  116

    Java学习笔记之------继承,抽象类,接口

    继承子类的实例化过程覆盖抽象接口

    继承

    作用:

    提高了代码的复用性让类与类之间产生联系,为第三个特征多态提供了前提。

    注:

    Java支持单继承(一个类只能有一个父类),不支持多继承(一个类可以有多个父类,C++支持)

    补充—继承体系:

    学习一个继承体系时,先看顶层,体系中的共性方法都在那里。了解该体系中具备的基本功能 使用时,找体系最下面的对象

    何时定义继承:

    当事物之间存在所属关系(is a)时,可以通过继承体现这个关系

    继承–私有的访问:

    对于父类中私有的部分,子类是无法直接访问的。一般使用set,get方法 class Person{ //父类属性私有 private String name; //set方法 public void setName(String name){ this.name = name; } public String getName(){ return this.name; } } class Student extends Person{ } public class PrivateDemo{ public static void main(String args[]){ Student s = new Student(); s.setName("lily"); String a = s.getName(); System.out.print(a); } }

    示例

    class species{ void show(){ System.out.println("吼叫"); } } class dog extends species{ void eat(){ System.out.println("骨头"); } } public class AbstractDemo{ public static void main(String args[]){ dog d = new dog(); d.eat(); d.show(); } }

    运行结果 注:

    当父类private权限时,子类的权限大于或者等于父类都是无效的,因为此时private与权限无关,表明父类方法私有,无法调用和访问。

    子类的实例化过程

    话不多说,直接上代码~

    class Father{ Father(){ System.out.println("I AM FATHER"); } } //子类继承父类 class Son extends Father{ Son(){ //有一个隐式的super();指向父类 System.out.println("I AM SON"); } } public class SuperDemo1{ public static void main(String args[]){ Son s = new Son(); } }

    效果图一出,惊了!子类会将父类中的构造方法一起运行,这是为啥?

    原来是因为,在子类中,所有的构造函数的第一行都有一个默认的隐式super()语句 那么为什么子类对象初始化要先访问父类中的构造函数呢 这是因为子类继承了父类中的内容,所以创建对象时要先看父类是如何对内容进行初始化的 这就是子类的实例化过程

    注意:

    当父类中没有空参数构造函数时,子类需要通过显示定义super()语句指定要访问父类中的构造函数。用来调用父类构造函数的super语句在子类构造函数必须在第一行,因为父类的初始化要先完成 class Father{ //Father类中没有空构造函数 Father(int x){ System.out.println("father"); } } //子类继承父类 class Son extends Father{ Son(){ //使用super显示定义 super(3); System.out.println("Son"); } Son(int x){ super(x); System.out.println("Son1"); } } public class SuperDemo1{ public static void main(String args[]){ Son s = new Son(3); } }

    一些疑问~

    this和super可以同时存在吗?

    不可以,因为它们都只能定义在第一行

    为什么需要定义在第一行?

    因为初始化动作要先完成

    覆盖

    当子父类中出现一样的方法时,子类对象运行的是子类的方法,这种特殊的情况,称为-----覆盖(override),又称重写,复写

    概念:返回值类型,函数名,参数列表完全一致(很重要)

    class father{ void show(){ System.out.println("show1"); } } //子类继承父类 class son extends father{ void show(){ System.out.println("show2"); } } public class ExtendDemo{ public static void main(String args[]){ son s = new son(); s.show(); } }

    解决方法-----super

    使用super方法指向父类中的同名方法。

    class father{ void show(){ System.out.println("show1"); } } //子类继承父类 class son extends father{ void show(){ System.out.println("show2"); //子类父类show方法重名,使用super指向父类中的show方法 super.show(); } } public class SuperDemo{ public static void main(String args[]){ son s = new son(); s.show(); } }

    注意1:

    子类方法覆盖父类方法,必须要保证权限大于等于父类。静态只能覆盖静态,或者被静态覆盖。 //父类中show方法静态修饰而子类show方法无静态修饰 class Father{ static void show(){ System.out.println("father run!"); } } class Son extends Father{ void show(){ System.out.println("son run!"); } } public class StaticOverride{ public static void main(String args[]){ Son s = new Son(); s.show(); } }

    注意2:Java中不支持子类的多继承,而是通过接口来解决,将多继承变成多实现。

    抽象

    描述一个事物时,如果没有充足的信息,则将该事物称为抽象事物

    特点:

    抽象方法都定义在抽象类中,都需要abstract修饰。抽象类不能实例化,即不能使用new关键字创建对象。子类要覆盖所有的抽象方法,子类具体化,子类可以创建对象。如果没有覆盖全部的抽象方法,子类还是一个抽象类。

    (在species类中加入一个抽象方法sleep,但子类dog没有覆盖sleep方法,则会报如下错误)

    abstract class species{ //在种类中,若此时并不知晓物种的具体吼叫方式,那么将其抽象,使用abstract abstract void bellow(); abstract void sleep(); }

    抽象类是不断的向上抽取而来的,抽取方法的声明但不确定具体的方法内容,由不同的子类来完成具体的方法内容。抽象类一定是一个父类。抽象类中可以不定义抽象方法,仅仅是为了让该类不创建对象,属于技巧应用。 abstract class species{ //在种类中,若此时并不知晓物种的具体吼叫方式,那么将其抽象,使用abstract abstract void bellow(); } class dog extends species{ void bellow(){ System.out.println("汪汪"); } void eat(){ System.out.println("骨头"); } } class cat extends species{ void eat(){ System.out.println("小鱼干"); } void bellow(){ System.out.println("喵喵"); } } public class AbstractDemo{ public static void main(String args[]){ dog d = new dog(); cat c = new cat(); d.eat(); d.bellow(); c.eat(); c.bellow(); } }

    运行结果 关于抽象类的几个问题 1.抽象类中有构造函数吗?

    有,抽象类中的构造函数虽然不能给抽象类对象实例化,因为抽象类无法创建对象,但抽象类有子类,他的构造函数可以给子类的对象实例化

    2.抽象类和一般类的区别?

    抽象类描述信息不具体,抽象类可以定义abstract方法,抽象类不可以实例化

    3.抽象关键字abstract不可以和哪些关键字共存?

    final,private,static

    接口

    javac编译后接口还是.class在interface中,即使没有写修饰符也可以编译通过,因为在interface内部有固定的修饰符,即使没有写,编译时仍旧默认存在的。 class species{ void sleep(){ System.out.println("sleep"); } void walk(){ System.out.println("walk"); } } interface InterA{ //即使没有写修饰符也可以,编译时会自动加上 //public abstract void guide(); void guide(); } class dog extends species implements InterA{ public void guide(){ System.out.println("导盲"); } } public class InterfaceDemo{ public static void main(String args[]){ dog d = new dog(); d.sleep(); d.walk(); d.guide(); } }

    注意:在调用接口的子类中,需要写权限修饰符,否则会报错 接口的特点:

    接口不可以实例化。子类需要覆盖接口中的全部抽象方法,才可以实例化。接口是被implements的接口可以多实现。 interface InterA{ void show1(); } interface InterB{ void show2(); } //接口多继承 class son implements InterA,InterB{ public void show1(){ System.out.println("show1"); } public void show2(){ System.out.println("show2"); } } public class ExtendDemo{ public static void main(String args[]){ son s = new son(); s.show1(); s.show2(); } }

    注:如果多实现的接口中方法名相同而内容不同,在调用时会出现不确定性。继承是为了获取基本功能,而接口是扩展功能。即使是使用接口中的某个方法,也需要全部覆盖,不然无法使用。 interface InterA{ void show1(); void show2(); void show3(); } class son implements InterA{ public void show1(){ System.out.println("show1"); } //需要全部覆盖 public void show2(){} public void show3(){} } public class ExtendDemo{ public static void main(String args[]){ son s = new son(); s.show1(); } }

    未完全覆盖报错信息

    为了方便创建接口的子类对象,可以先创建一个类将接口中的方法全部实现,因该类的创建没有意义,所以将其抽象。之后的类需要接口中的内容时,就不需要完全覆盖,只需要继承该类。 abstract class demo implements InterA{ public void show1(){}; public void show2(){}; public void show3(){}; } interface InterA{ void show1(); void show2(); void show3(); } class son extends demo{ //implement InterA{ public void show2(){ System.out.println("show2"); } //public void show1(){} //public void show3(){} } public class ExtendDemo{ public static void main(String args[]){ son s = new son(); s.show2(); } }

    接口的思想

    接口的出现扩展了功能。接口其实就是暴露出来的规则。接口的出现降低了耦合性,即解耦一方使用接口,一方实现接口

    接口和抽象类的区别

    类与类之间是extends关系,是is和a。类和接口是implements关系,是like和a.抽象类中可以定义抽象和非抽象方法,子类可以直接使用,或覆盖使用。接口中定义都是抽象方法,必须实现才可使用。

    该文章为学习笔记,如有不足之处还请指正

    Processed: 0.026, SQL: 8