• 9.继承


    继承

    继承概述

    面向对象三大特征之一, 可以使得子类具有父类的属性和方法, 还可以在子类中重新定义, 追加属性和方法.

    继承格式:

    • public class 子类名 extends 父类名{}

    范例

    • public class child extends parent{}

    • child: 子类,也称为派生类

    • parent: 父类,也称为基类, 超类

    例子

    demo

    package classInherit;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建对象
            parent p = new parent();
            p.show();
    
            child c = new child();
            c.method();
            c.show();  // 子类调用父类的show方法
        }
    }
    
    

    child

    package classInherit;
    
    public class child extends parent {  // 继承父类
        public void method() {
            System.out.println("子类method方法");
        }
    }
    

    parent

    package classInherit;
    
    public class parent {
        public void show() {
            System.out.println("父类show方法");
        }
    }
    

    继承的好处和弊端

    好处

    • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
    • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

    弊端

    • 类的耦合性增强, 当父类发生变化时子类实现也不得不跟随变化,削弱了子类的独立性

    使用子类的场景

    • 继承体现的关系: is

    注意:

    • 如果子类想要访问父类中的属性, 那么父类中的属性必须定义为public.
    • 子类和父类中有相同的属性或方法,会优先使用子类的属性或方法.

    继承中变量访问特点

    在子类中访问一个变量

    1. 子类局部范围查找
    2. 子类成员范围找
    3. 父类成员范围找

    如果都没有会报错

    super关键字

    super关键字和this关键字用法相似

    • this: 代表本类对象的引用
    • super: 代表父类存储空间的表示(可以理解为父类对象的引用)
    关键字 访问成员变量 访问构造方法 访问成员方法
    this this.成员变量: 访问本类成员变量 this(...): 访问本类的构造方法 this.成员方法(...): 访问本类成员方法
    super super.成员变量: 访问父类成员变量 super(...): 访问父类构造方法 super.成员方法(...): 访问父类成员方法

    例子

    package classInherit;
    
    public class child extends parent {  // 继承父类
        // 身高
        public int height = 175;
        public int age = 30;
        public void show() {
            int age = 40;
            System.out.println("子类method方法");
            System.out.println(this.height);
            // 访问age, 先局部,后子类,最后父类
            System.out.println(age);
    
            System.out.println("子类成员变量: " + this.age);
            System.out.println("父类成员变量: " + super.age);
        }
    }
    

    构造方法访问特点

    子类中所有的构造方法默认都会访问父类中无参的构造方法

    • 子类会继承父类的数据,可能还会使用父类的数据, 所以, 子类初始化之前, 一定要先完成父类数据的初始化
    • 每一个子类构造方法的第一条语句默认都是: super(),

    如果父类中没有无参改造方法, 只有带参构造方法, 子类构造方法直接会报错

    • 可以在子类中通过super手动调用父类的带参构造方法来避免.
    • 在父类中提供一个无参构造方法(推荐)

    Parent

    package classInherit.initialMethod;
    
    public class Parent {
        /*
        public Parent() {
            System.out.println("Parent中无参构造方法");
        }
        */
        public Parent(int age) {
            System.out.println("Parent中带参构造方法");
        }
    }
    
    

    child

    package classInherit.initialMethod;
    
    public class Child extends Parent {  // 继承父类
        public Child() {
            super(20);
            System.out.println("Child中无参构造方法");
        }
        public Child(int age) {
            super(20);
            System.out.println("Child中带参构造方法");
        }
    }
    
    

    Demo

    package classInherit.initialMethod;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建对象
            Child c = new Child();
            System.out.println("-----------手动分割----------");
            Child c2 = new Child(20);
        }
    }
    
    

    成员方法访问特点

    通过子类对象访问一个方法

    • 子类成员范围查找
    • 父类成员范围查找
    • 如果都没有会报错,(不考虑父亲的父亲)

    parent

    package classInherit.memberMethod;
    
    public class Parent {
        public void show() {
            System.out.println("Parent中show方法被调用");
        }
    }
    
    

    child

    package classInherit.memberMethod;
    
    public class Child extends Parent {  // 继承父类
        public void method() {
            System.out.println("Child中method方法被调用");
        }
        public void show() {
            super.show();
            System.out.println("Child中show方法被调用");
        }
    }
    
    

    demo

    package classInherit.memberMethod;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建对象
            Child c = new Child();
            c.method();
            c.show();
            // c.test();  // 报错
        }
    }
    
    

    方法重写

    子类中出现了和父类中一模一样的方法申明, 内容但是方法内容不一致

    • 当子类需要父类的功能, 而功能主体子类有自己特有内容时, 可以重写父类中的方法, 这样, 既沿袭了父类的功能, 又定义了子类特有的内容

    @Override

    • 是一个注解
    • 可以帮助我们检查重写方法声明的正确性

    Phone

    package classInherit.methodRewrite;
    
    public class Phone {
        public void call(String name) {
            System.out.println("给" + name + "打电话");
        }
    }
    

    NewPhone

    package classInherit.methodRewrite;
    /*
        新手机
     */
    public class NewPhone extends Phone {
        /*
        public void call(String name) {
            System.out.println("开启视频功能!");
            // System.out.println("给" + name + "打电话");
            super.call(name);
        }
         */
    
        @Override
        public void call(String name) {
            System.out.println("开启视频功能!");
            // System.out.println("给" + name + "打电话");
            super.call(name);
        }
    }
    
    

    Demo

    package classInherit.methodRewrite;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建对象,调用方法
            Phone p = new Phone();
            p.call("ryxiong");
    
            System.out.println("-------");
    
            NewPhone p2 = new NewPhone();
            p2.call("ryxiong");
        }
    }
    
    

    注意事项:

    • 父类的私有方法, 子类无法访问, 所以也无法重写

    • 子类方法访问权限不能更低(public > 默认 > 私有)

    继承的注意事项

    java中只支持单继承, 不支持多继承

    java类中支持多层继承

    GrandFather

    package classInherit.inheritNotes;
    
    public class GrandFather {
        public void drink() {
            System.out.println("爷爷爱喝酒");
        }
    }
    

    Father

    package classInherit.inheritNotes;
    
    public class Father extends GrandFather {
        public void sing() {
            System.out.println("爸爸爱唱歌");
        }
    }
    

    Mother

    package classInherit.inheritNotes;
    
    public class Mother {
        public void dance() {
            System.out.println("妈妈爱跳舞");
        }
    }
    
    

    Son

    package classInherit.inheritNotes;
    
    public class Son extends Father {
    
    }
    
    

    案例

    Person

    package classInherit.inheritPractice;
    
    public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    

    Teacher

    package classInherit.inheritPractice;
    
    public class Teacher extends Person {
        public Teacher() {
        }
    
        public Teacher(String name, int age) {
            super(name, age);
        }
    
        public void teach() {
            System.out.println("用爱成就每一位学员");
        }
    }
    
    

    Demo

    package classInherit.inheritPractice;
    /*
        测试类
     */
    
    public class Demo {
        public static void main(String[] args) {
            // 创建老师类
            Teacher t1 = new Teacher();
            t1.setName("林青霞");
            t1.setAge(30);
            System.out.println(t1.getName() + "," + t1.getAge());
            t1.teach();
    
            // 带参构造方法
            Teacher t2 = new Teacher("风清扬", 33);
            System.out.println(t2.getName() + "," + t2.getAge());
            t2.teach();
        }
    }
    
    

    本质上就是文件夹

    作用: 对类进行分类管理

    包的定义格式

    • 格式: package 包名; 多级包用.分开
    • 范例: package com.itheima;

    带包的java类编译和执行

    • 手动建包
      • 按照以前格式编译java文件: javac HelloWorld.java
      • 手动创建包, 创建文件夹com/itheima/
      • 将class文件放到文件夹com/itheima/下
      • 带包执行 java com.itheima.HelloWorld
    • 自动建包
      • Javac -d . HelloWrold.java
      • java com.itheima.HelloWorld

    修饰符

    修饰符权限

    修饰符 同一类中 同一个包中子类无关类 不同包的子类 不同包的无关系
    private
    默认
    protected
    public

    pkgs.Parent

    package modifier.pkgs;
    
    public class Parent {
        private void show1() {
            System.out.println("private");
        }
    
        void show2() {
            System.out.println("default");
        }
    
        protected void show3() {
            System.out.println("protected");
        }
    
        public void show4() {
            System.out.println("public");
        }
    
        public static void main(String[] args) {
            // 创建父类对象,测试哪些方法可以使用
            Parent p = new Parent();
            p.show1();
            p.show2();
            p.show3();
            p.show4();
        }
    }
    
    

    pkgs.Child

    package modifier.pkgs;
    
    public class Child extends Parent {
        public static void main(String[] args) {
            // 创建Child对象,测试哪些方法可以使用
            Child c = new Child();
            c.show2();
            c.show3();
            c.show4();
        }
    }
    
    

    pkgs.Demo

    package modifier.pkgs;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建Parent类对象, 测试看看哪些可以使用
            Parent p = new Parent();
            p.show2();
            p.show3();
            p.show4();
        }
    }
    
    

    test.Child

    package modifier.test;
    
    import modifier.pkgs.Parent;
    
    public class Child extends Parent {
        public static void main(String[] args) {
            // 创建Child对象,测试看看哪些方法可以使用
            Child c = new Child();
            c.show3();
            c.show4();
        }
    }
    
    

    test.Demo

    package modifier.test;
    
    public class Demo {
        public static void main(String[] args) {
            // 创建Child对象,测试看看哪些方法可以使用
            Child c = new Child();
            c.show4();
        }
    }
    
    

    final修饰符

    表示最终, 可以修饰成员方法, 成员变量, 类

    final特点:

    • 修饰方法: 最终方法, 不能被重写
    • 修饰变量: 变量为常量, 不能再次被赋值
    • 修饰类: 该类为最终类, 不能被继承

    parent

    package modifier.finalDemo;
    
    // 被final修饰的类,不能被继承
    /*
    public final class Parent {
        public final void method() {
            System.out.println("Parent method");
        }
    }
    */
    
    public class Parent {
        public final void method() {
            System.out.println("Parent method");
        }
    }
    

    child

    package modifier.finalDemo;
    
    public class Child extends Parent {
        public final int age = 20; // 被final修饰的值不能被修改
        public void show() {
            // age = 100;
            System.out.println(age);
        }
    
        /*
        @Override  // 被final修饰的方法不能重写
        public void method() {
            System.out.println("Child Method");
        }
         */
    }
    
    

    Demo

    package modifier.finalDemo;
    
    public class Demo {
        public static void main(String[] args) {
            Child c = new Child();
            c.method();
            c.show();
        }
    }
    
    

    final修饰局部变量

    • 修饰基本类型: final修饰指的是基本类型的数据值不能发生改变

    • 修饰引用类型: final修饰值得是引用类型地址值不能发生改变, 但是地址里面的内容可以发生改变.

    Student

    package modifier.finalDemo;
    
    public class Student {
        public int age = 20;
    }
    
    

    FinalDemo

    package modifier.finalDemo;
    
    public class FinalDemo {
        public static void main(String[] args) {
            // final修饰基本类型变量
            final int age = 20;
            // age = 100;
            System.out.println(age);
    
            // final修饰引用类型变量
            final Student s = new Student();
            s.age = 100;  // s是指一个地址, 内容可以变, 但是地址不能变
            System.out.println(s.age);
    
            // s = new Student();  // final修饰后, 地址值不能改变
    
        }
    }
    
    

    Static修饰符

    static 关键字是静态的意思, 可以修饰成员方法, 成员变量

    static 修饰的特点

    • 被类的所有对象共享: 这也是我们判断是否使用静态关键字的条件

    • 可以通过类名调用, 也可以使用对象名调用, 推荐使用类名

    Student

    package modifier.staticDemo;
    
    public class Student {
        public String name;
        public int age;
    //    public String university;
        public static String university;  // 所有对象能够共享的属性, 用static修饰
    
        public void show() {
            System.out.println(name + "," + age + "," + university);
        }
    }
    
    

    StaticDemo

    package modifier.staticDemo;
    
    public class StaticDemo {
        public static void main(String[] args) {
            // static属性直接通过类来赋值
            Student.university = "传智大学";
            Student s1 = new Student();
            s1.name = "林青霞";
            s1.age = 30;
            // s1.university = "传智大学";
            s1.show();
    
            Student s2 = new Student();
            s2.name = "风清扬";
            s2.age = 33;
            s2.show();
        }
    }
    
    

    static访问特点

    非静态成员方法

    • 能访问静态的成员变量
    • 能访问非静态的成员变量
    • 能访问静态的成员方法
    • 能访问非静态的成员方法

    静态成员方法

    • 能访问静态的成员变量
    • 能访问讲台成员方法

    静态成员只能访问静态成员

    Student1

    package modifier.staticDemo;
    
    public class Student1 {
        // 非静态成员变量
        private String name = "林青霞";
        // 静态成员变量
        private static String university = "传智大学";
    
        // 非静态成员变量
        public void show1() {
        }
    
        // 非静态成员方法
        public void show2() {
            System.out.println(name);
            System.out.println(university);
            show1();
            show3();
        }
    
        // 静态成员方法
        public static void show3() {
    
        }
    
        // 静态成员方法
        public  static void show4() {
            // System.out.println(name);  // 无法访问
            System.out.println(university);
            // show1();  // 无法访问
            show3();
        }
    }
    
    
  • 相关阅读:
    java-正则表达式6
    java-正则表达式5
    java-正则表达式4
    java-正则表达式3
    java-正则表达式2
    12.5
    JAVA GUI随笔
    JAVA个人知识总结
    UML关系图
    JAVA中的聚集和组合的区别和联系
  • 原文地址:https://www.cnblogs.com/ryxiong-blog/p/13890196.html
Copyright © 2020-2023  润新知