• java 19.继承


    继承

    共性抽取

    类的继承格式

    class 父类 {
    }
     
    class 子类 extends 父类 {
    }
    

    继承的关系:is-a,父类更通用,子类更具体。

    java单继承,java不支持多继承,支持多级继承

    继承的特性

    • 子类拥有父类非 private 的属性、方法。
    • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
    • 子类可以用自己的方式实现父类的方法。
    • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
    • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

    继承关键字

    继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

    extends关键字

    在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

    public class Animal { 
        private String name;   
        private int id; 
        public Animal(String myName, String myid) { 
            //初始化属性值
        } 
        public void eat() {  //吃东西方法的具体实现  } 
        public void sleep() { //睡觉方法的具体实现  } 
    } 
     
    public class Penguin  extends  Animal{ 
    }
    

    implements关键字

    使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

    public interface A {
        public void eat();
        public void sleep();
    }
     
    public interface B {
        public void show();
    }
     
    public class C implements A,B {
    }
    

    继承中成员变量的访问特点

    在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:

    1. 直接通过子类对象访问成员变量:等号左边时谁,就优先用谁,没有则向上找

    2. 间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上找

    示例代码

    父类子类都有一个变量num

    package extendsDemo;
    
    //父类
    public class Fu {
        int num = 10;
        int numFu = 20;
    
        public void methodFu() {
            System.out.println(num);
        }
    }
    
    //子类
    package extendsDemo;
    
    public class Zi extends Fu{
        int numZi = 100;
        int num = 200;
    
        public void methodZi() {
            System.out.println(num);
        }
    }
    
    //demo
    package extendsDemo;
    
    public class demoFuZi {
        public static void main(String[] args) {
            Fu fu = new Fu();
            Zi zi = new Zi();
    
            System.out.println(zi.num);  //200
            System.out.println("------------------");
            zi.methodZi();  //200
            zi.methodFu();  //10
        }
    }
    

    区分子类方法中重名的三种

    父类成员变量:直接写成员变量名

    子类成员变量:this.成员变量名

    子类方法的局部变量:super.成员变量名

    Fu.java

    package extendsDemo;
    
    public class Fu {
        int num = 10;
    }
    

    Zi.java

    package extendsDemo;
    
    public class Zi extends Fu{
        int num = 20;
    
        public void methodZi() {
            int num = 30;
            System.out.println(num);  //30 局部变量
            System.out.println(this.num);  //20 本类的成员变量
            System.out.println(super.num);  //10 父类的成员变量
        }
    }
    

    demoFuZi.java

    package extendsDemo;
    
    public class demoFuZi {
        public static void main(String[] args) {
            Zi zi = new Zi();
            zi.methodZi();
        }
    }
    

    继承中成员方法的访问特点

    在父子类的继承关系中,创建子类对象,访问成员方法的规则:创建的对象是谁,就优先用谁,如果没有则向上找。

    注意事项:无论时成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。

    示例代码

    Fu.java

    public class Fu {
        public void method() {
            System.out.println("执行父类的方法");
        }
    }
    

    Zi.java

    public class Zi extends Fu{
        public void method() {
            System.out.println("执行子类的方法");
        }
    }
    

    demoFuZi.java

    public class demoFuZi {
        public static void main(String[] args) {
            Zi zi = new Zi();
            zi.method();
        }
    }
    

    java方法中的覆盖重写

    重写:Override 在继承关系中,方法的名称一样,参数列表也一样

    重载:OverLoad 在继承关系中,方法的名称一样,参数列表不一样

    @Override 写在方法前面,用来检测是不是有效的正确覆盖重写。只是检测,方法是重写的话,不写@Override也是重写的。

    子类方法的返回值必须小于等于父类方法的返回值范围

    java.lang.object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类

    子类方法的权限必须大于等于父类方法的权限修饰符

    public > protected > (default) > private
    

    default不是关键字default,而是什么都不写,留空。

    覆盖重写应用

    设计原则:对于已经投入使用的类,尽量不要进行修改。推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容。

    示例代码

    Fu.java

    public class Fu {
        public void call() {
            System.out.println("打电话");
        }
        public void send() {
            System.out.println("发短信");
        }
        public void show() {
            System.out.println("显示号码");
        }
    }
    

    Zi.java

    public class Zi extends Fu{
        public void show() {
            super.show();  //把父类的show方法拿过来重复利用
            System.out.println("显示姓名");
            System.out.println("显示头像");
        }
    
    }
    

    demoFuZi.java

    public class demoFuZi {
        public static void main(String[] args) {
            Fu fu = new Fu();
            fu.call();
            fu.send();
            fu.show();
            System.out.println("---------------");
            Zi zi = new Zi();
            zi.call();
            zi.send();
            zi.show();
        }
    }
    

    继承中构造方法的访问特点

    1. 在子类构造方法中有一个默认隐含的**“super()”调用父类无参构造方法**(不写编译器也会加上),所以一定是先调用父类构造,后执行子类构造。
    2. 可以通过super关键字在子类构造方法中调用父类重载构造。
    3. super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。

    总结:子类必须调用父类构造方法,不写则编译器自动加super(),写了则用写的指定的super调用,super只能有一个,还必须是第一个。

    示例代码

    Fu.java

    public class Fu {
    
        public Fu(){
            System.out.println("父类无参构造");
        }
        public Fu(int num){
            System.out.println("父类有参构造");
        }
    }
    

    Zi.java

    public class Zi extends Fu{
    
        public Zi(){
            super();  //在调用父类无参构造方法,编译器会自动加上super()
    //        super(10);  //通过super关键字在子类构造方法中调用父类重载构造
            System.out.println("子类构造方法");
        }
    }
    

    demoFuZi.java

    public class demoFuZi {
        public static void main(String[] args) {
            Zi zi = new Zi();
        }
    }
    

    super关键字的三种用法

    1. 在子类的成员方法中,访问父类的成员变量
    2. 在子类的成员方法中,访问父类的成员方法
    3. 在子类的构造方法中,访问父类的构造方法

    示例代码

    Fu.java

    public class Fu {
    
        int num = 10;
        public void method(){
            System.out.println("父类方法");
        }
    }
    

    Zi.java

    public class Zi extends Fu{
    
        int num = 20;
        public void methodZi(){
            System.out.println(super.num);  //子类访问父类成员变量
        }
        public void method(){
            super.method();
            System.out.println("子类调用父类成员方法");
        }
        public Zi(){
            super();  // 3
            System.out.println("子类构造方法调用父类构造方法");
        }
    }
    

    demoFuZi.java

    public class Zi extends Fu{
    
        int num = 20;
        public void methodZi(){
            System.out.println(super.num);  //子类访问父类成员变量
        }
        public void method(){
            super.method();
            System.out.println("子类调用父类成员方法");
        }
        public Zi(){
            super();  // 3
            System.out.println("子类构造方法调用父类构造方法");
        }
    }
    

    this关键字的三种用法

    super关键字用来访问父类内容,而this关键字用来访问本类内容。用法三种:

    1. 在本类的成员方法中,访问本类的成员变量
    2. 在本类的成员方法中,访问本类的另一个成员方法
    3. 在本类的构造方法中,访问本类的另一个构造方法

    在第三种用法中要注意:

    a. this(…)调用必须是构造方法的第一个语句,唯一一个。

    b. super和this两种构造调用,不能同时使用。

    示例代码

    Fu.java

    public class Fu {
    
        int num = 10;
        public void method(){
            System.out.println("父类方法");
        }
    }
    

    Zi.java

    public class Zi extends Fu{
    
        int num = 20;
        //在本类的成员方法中,访问本类的成员变量
        public void showNum(){
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(super.num);
            System.out.println("-----------------");
    
        }
        //在本类的成员方法中,访问本类的另一个成员方法
        public void methodA(){
            System.out.println("AAA");
        }
        public void methodB(){
            this.methodA();
            System.out.println("BBB");
        }
        //在本类的构造方法中,访问本类的另一个构造方法
        public Zi(){
            this(123);  //本类的无参构造调用本类的有参构造
        }
        public Zi(int n){
            this(1,2);
        }
        public Zi(int n, int m){
    //        this();  //错误写法
        }
    }
    

    super与this关键字图解
    super与this关键字图解

  • 相关阅读:
    Python 从入门到进阶之路(一)
    Egg 企业级应用开发框架的搭建
    koa2 从入门到进阶之路 (七)
    koa2 从入门到进阶之路 (六)
    koa2 从入门到进阶之路 (五)
    衣服洗一个月之后失踪,这个互联网洗衣平台把衣服洗出了翅膀
    CSS3 Gradient 渐变还能这么玩
    MessageChannel 消息通道
    前端面试(算法篇)
    JavaScript 中的相等操作符 ( 详解 [] == []、[] == ![]、{} == !{} )
  • 原文地址:https://www.cnblogs.com/kknote/p/16103413.html
Copyright © 2020-2023  润新知