>  기사  >  Java  >  Java 상속 및 다형성의 개념 및 구현 방법 소개

Java 상속 및 다형성의 개념 및 구현 방법 소개

WBOY
WBOY앞으로
2023-04-27 15:46:081345검색

    1. 상속

    1. 상속의 개념

    상속 메커니즘: 객체 지향 프로그래밍은 코드 재사용의 가장 중요한 수단으로, 프로그래머가 원래 클래스의 특성을 유지할 수 있도록 해줍니다. 새 함수가 생성되면 생성된 새 클래스는 파생 클래스/하위 클래스가 됩니다. 상속이 해결하는 주요 문제는 공통 기능 추출과 코드 재사용 실현입니다.

    Java 상속 및 다형성의 개념 및 구현 방법 소개

    2. 상속 구문

    은 클래스 간의 상속 관계를 나타냅니다. 구문은 다음과 같습니다.

    modifier class subclass/derived class extends parent class/base class/superclass

                                                                             당신만의 고유한 멤버는 기본 클래스와의 차이점을 반영합니다

    3 . 상위 클래스 멤버 액세스
    • (1) 하위 클래스에서 상위 클래스의 멤버 변수에 액세스할 때

    • 같은 이름이면 그냥 정상적으로 접근하세요

    같은 이름의 멤버 변수가 있습니다. (super.variable 이름)을 사용하여 상위 클래스 멤버 변수에 대한 접근을 구현합니다.

    public class Base {
        int a;
        int b;
        int c;
    } 
    public class Derived extends Base{
        int a; // 与父类中成员a同名,且类型相同
        char b; // 与父类中成员b同名,但类型不同
        public void method(){
            a = 100; // 访问父类继承的a,还是子类自己新增的a?
            b = 101; // 访问父类继承的b,还是子类自己新增的b?
            c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
        }
    }
    • 멤버 변수에 접근할 때 접근합니다. 먼저 자신의 멤버 변수를 사용하세요. 즉, 동일한 이름의 멤버 변수에 접근할 경우 서브클래스에 대한 접근이 우선적으로 적용됩니다. 즉, 하위 클래스는 상위 클래스의 멤버를 숨깁니다

    • 멤버 변수 액세스는 근접성 원칙을 따릅니다. 해당 클래스가 없으면 상위 클래스에서 우선적으로 찾습니다. 수업.

    (2) 하위 클래스에서 상위 클래스의 멤버 메소드에 액세스
    • 멤버 메소드는 이름이 다르므로 정상적으로 액세스할 수 있습니다.
    • 멤버 메소드는 이름이 같으므로 다음에 액세스할 수 있습니다. [super.method 이름] 메소드를 통해 동일한 이름을 가진 상위 클래스 메소드
    상위 클래스와 하위 클래스에서 동일한 이름을 가진 메소드의 매개변수 목록이 다른 경우(오버로드), 해당 매개변수를 기반으로 접근할 적절한 메소드를 선택합니다. 메소드를 호출할 때 전달됩니다.
    • 부모 클래스와 하위 클래스의 이름이 같은 메서드의 프로토타입이 일치하면 하위 클래스의

      4.super 키워드에 액세스합니다.
    • super 키워드의 주요 기능은 해당 클래스의 멤버에 액세스하는 것입니다. 하위 클래스 메서드에서 동일한 이름을 가진 상위 클래스입니다. (비정적 메소드에서만 사용 가능)

      public class Base {
          int a;
          int b;
          public void methodA(){
              System.out.println("Base中的methodA()");
          }
          public void methodB(){
              System.out.println("Base中的methodB()");
      }
      public class Derived extends Base{
          int a; 
          char b; 
          // 与父类中methodA()构成重载
          public void methodA(int a) {
              System.out.println("Derived中的method()方法");
          }
          // 与父类中methodB()构成重写
          public void methodB(){
              System.out.println("Derived中的methodB()方法");
          }
          public void methodC(){
              a = 100; // 等价于: this.a = 100;
              b = 101; // 等价于: this.b = 101;
              // 访问父类的成员变量时,需要借助super关键字
              // super是获取到子类对象中从基类继承下来的部分
              super.a = 200;
              super.b = 201;
              methodA(); // 没有传参,访问父类中的methodA()
              methodA(20); // 传递int参数,访问子类中的methodA(int)
              methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到
              super.methodB(); // 访问基类的methodB()
          }
      }

      5. 서브클래스 생성 메소드
    하위 클래스 객체를 생성할 때는 먼저 상위 클래스의 생성 메소드를 호출한 후 서브클래스의 생성 메소드를 실행해야 합니다.

    public class Base {
        public Base(){
            System.out.println("Base()");
        }
    }
    public class Derived extends Base{
        public Derived(){
       // super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
       // 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
       // 并且只能出现一次
            System.out.println("Derived()");
        }
    }

    상위 클래스가 매개변수 없는 생성자 또는 기본 생성자를 명시적으로 정의하는 경우 하위 클래스 생성자의 첫 번째 줄에 기본적으로 암시적 super() 호출이 있습니다.

    상위 클래스가 매개변수를 사용하여 생성자를 정의하면 컴파일러는 더 이상 하위 클래스에 대한 기본 생성자를 생성하지 않습니다. 하위 클래스는 명시적으로 정의되어야 하며 적절한 상위 클래스 생성자는 하위 클래스 생성자에서 호출됩니다

    하위 클래스 생성 메서드에서 super(……)는 상위 클래스 생성 메서드를 호출하며 반드시 하위 클래스 생성 메서드의 첫 번째 문이어야 합니다
    • super(……)는 하위 클래스 생성에서만 사용할 수 있는 것으로 나타납니다. this
    • 6. super 및 this
    • super와 동시에 나타날 수 없으며 this는 멤버 메서드에서 멤버 변수에 액세스하고 다른 멤버 함수를 호출하는 데 사용할 수 있습니다. 첫 번째 생성자 A 문, 그렇다면 이들 사이의 차이점은 무엇입니까?

      (1) 동일한 점
    • 은 모두 Java 키워드입니다.

    클래스의 비정적 메서드에서만 사용할 수 있으며 비정적 멤버 메서드 및 속성에 액세스하는 데 사용됩니다.

    을 사용해야 합니다. as constructors 의 첫 번째 문과 동시에 존재할 수 없습니다
    • (2) 차이점
    • 이것은 현재 객체에 대한 참조이고, super는 하위 클래스의 상위 클래스에서 상속된 멤버에 대한 참조입니다. object
    • this는 정적 멤버 메서드의 숨겨진 매개 변수가 아니며 super는 숨겨진 매개 변수가 아닙니다.

    생성자 메서드에서 this()는 이 클래스의 생성자 메서드를 호출하는 데 사용되며 super()는 상위 클래스 생성자 메서드를 호출하는 데 사용되며 두 호출이 동시에 발생할 수 없습니다. 생성자 메서드에서
    • 하위 클래스의 생성자 메서드에는 확실히 super() 호출이 있지만 this()는 존재하지 않습니다. 사용자가 작성하지 않은 경우
    • 7. 코드 블록 실행 순서
    • [일반 클래스]

    • 정적 코드 블록은 클래스 로딩 단계에서 처음으로 한 번만 실행됩니다.

    객체가 생성되면 인스턴스 코드 블록이 실행되고 마지막으로 생성자 메서드가 실행됩니다

    [상속 관계에 따른 실행 순서 ]
    • 상위 클래스 정적 코드 블록이 하위 클래스 정적 코드 블록보다 우선합니다. 가장 빠른 실행
    • 상위 클래스 인스턴스 코드 블록과 상위 클래스 생성 메소드가 즉시 실행됩니다

    인스턴스 코드 블록과 서브 클래스 생성 메소드가 마지막에 실행됩니다
    • 하위 클래스 객체가 실행될 때 두 번째로 인스턴스화되면 상위 클래스와 하위 클래스의 정적 코드 블록은 다시 실행되지 않습니다

    8、继承方式

    【注】Java中不支持多继承

    Java 상속 및 다형성의 개념 및 구현 방법 소개

    • super只能指代直接父类

    • 继承关系一般不超过三层

    9、final关键字

    • 修饰变量时,表示常量(不能修改)

    • 修饰类:此类不能被继承

    • 修饰方法:表示方法不能被重写

    10、继承和组合

    组合和继承都能实现代码的复用。组合没有涉及到特殊的语法(如extend关键字),仅仅是将一个类的实例作为另一个类的属性。

    • 继承表示对象与对象之间是is-a的关系

    • 组合表示对象与对象之间是has-a的关系

    一般建议:能用组合尽量用组合

    二、多态

    1、向上转型

    通过父类类型的引用调用子类对象,向上转型是安全的

    【发生向上转型的时机】

    • 直接赋值

    • 方法传参

    • 函数的返回值

    public class TestAnimal {
        // 2. 函数传参:形参为父类引用,可以接收任意子类的对象
        public static void eatFood(Animal a) {
            a.eat();
        }
     
        // 3. 作返回值:返回任意子类对象
        public static Animal buyAnimal(String var) {
            if ("狗" == var) {
                return new Dog("狗狗", 1);
            } else if ("猫" == var) {
                return new Cat("猫猫", 1);
            } else {
                return null;
            }
        }
     
        public static void main(String[] args) {
            Animal cat = new Cat("元宝", 2); // 1. 直接赋值:子类对象赋值给父类对象
            Dog dog = new Dog("小七", 1);
        }
    }

    优缺点:

    • 优点:让代码更加灵活

    • 缺点:不能访问到子类特有的方法

    2、重写

    函数名相同、参数列表相同、返回值相同或是【协变类型】(父子类关系)

    【方法重写的规则】

    • 重写的方法访问权限不能比父类中原方法的的权限低;

    • 父类中被static、private、final修饰的方法、构造方法不能被重写;

    • 重写的方法,可以使用 @override 注解来显示指定(帮助我们进行一些合法性的检验)。比如方法名拼写错误,编译会报错;

    • 重写的返回值类型可以不同,但是必须具有父子关系。

    • 被final修饰的方法,叫做密封方法,该方法不能被重写。

    • 外部类只能是public或者默认权限

    【动态绑定和静态绑定】

    • 动态绑定:发生的条件(1、父类引用引用子类对象;2、通过父类引用,可以访问到子类中的方法)。后期绑定,即在编译时不能确定方法的行为,需要等到程序运行时,才能够确定调用哪个类的方法;

    • 静态绑定:前期绑定,编译时,根据用户传递的参数类型确定具体的调用方法(函数重载)

    3、多态

    一个引用调用同一个方法,可以表现出不同的形式,这种思想称为多态。在父类的构造方法中不要调用重写的方法。

    【多态实现的条件】

    • 必须在继承条件下

    • 子类对父类方法进行重写

    • 通过父类引用调用重写的方法

    • 发生了向上转型

    public class Animal(){
        String name;
        int age;
        public Animal(String name, int age){
            this.name = name;
            this.age = age;
        }
        public void eat(){
            System.out.println(name + "吃饭");
            }
    }
    public class Cat extends Animal{
        public Cat(String name, int age){
            super(name, age);
        }
        @Override
        public void eat(){
            System.out.println(name+"吃鱼~~~");
        }
    }
    public class Dog extends Animal {
        public Dog(String name, int age){
            super(name, age);
        }
        @Override
        public void eat(){
            System.out.println(name+"吃骨头~~~");
        }
    }
    public class TestAnimal {
        // 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
       // 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
       // 注意:此处的形参类型必须时父类类型才可以
        public static void eat(Animal a){
            a.eat();
        }
        public static void main(String[] args) {
            Animal animal1 = new Cat("元宝",2);
            Animal animal2 = new Dog("小七", 1);
            eat(animal1);
            eat(animal2);
        }
    }

    【注】Java中所有的类默认继承Object类

    위 내용은 Java 상속 및 다형성의 개념 및 구현 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제