다형성이란 무엇인가요? ? 문자 그대로 이해하면 여러 형태, 즉 서로 다른 클래스에 의해 인스턴스화된 개체가 동일한 메서드를 호출하는 것을 의미합니다. 또한 서로 다른 클래스의 개체가 동일한 동작 후에 서로 다른 상태를 생성하는 것으로 이해될 수도 있습니다.
다형성을 이해하려면 상향 변환과 재작성의 두 가지 핵심 사항을 이해한 다음 상향 변환과 재작성을 읽은 후 다형성의 개념을 살펴보겠습니다. 깨달음을 얻었고 훨씬 더 깨달아졌습니다. 다형성의 조건은 상향변형, 재작성, 상속이기 때문이다.
우선 다형성의 전제는 상속이기 때문에 상위 클래스와 하위 클래스 사이에 관계가 있어야 합니다.
하위 클래스 객체와 상위 클래스 객체를 생성하는 방법을 기억해 봅시다.
class Animal{ public String name;//名字 public int age; public void eat() { System.out.println("我要吃饭!!!"); } public void sleep() { System.out.println("我要睡觉!!!"); } } class Cat extends Animal{ public void mew() { System.out.println("喵喵喵!!!"); } } public class TestDemo1 { public static void main(String[] args) { Cat cat =new Cat();//实例化子类对象 cat.name="mimi"; Animal animal = new Animal();//实例化父类对象 animal.eat(); } }
여기서 Cat 클래스가 생성된 후 Animal 클래스를 상속받습니다. Cat 및 Animal 개체를 인스턴스화하여 메서드와 속성을 호출할 수 있습니다.
그렇다면 상향변형이란 무엇일까요? ? ?
원래는 하위 클래스 객체의 참조가 하위 클래스의 객체를 참조하는 것입니다. 이것이 상향 변환입니다.
코드를 사용하여 이해해 보겠습니다.
이는 상향 변환입니다. 또한 동물을 메서드 호출을 위한 상위 클래스 참조로 사용할 수도 있습니다. 상위 클래스를 호출하기 위한 참조입니다. 클래스의 메서드와 속성은 호출할 수 없지만 하위 클래스의 메서드와 속성은 호출할 수 없습니다. 그렇다면 왜 그럴까요? ? 그 이유는 상위 클래스의 하위 클래스에는 이 메서드가 없기 때문에 호출할 수 없기 때문입니다. 요약: 상향 변환 중에 상위 클래스 참조는 하위 클래스 개체를 참조합니다. 이 상위 클래스 참조는 하위 클래스가 아닌 상위 클래스의 속성과 메서드만 호출할 수 있습니다.
상향 변환의 세 가지 형태
첫 번째는 직접 할당즉, 위에서 작성한 방식입니다.Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型 Animal animal2 = new Dog();
세 번째는 다음과 같습니다. 반환 값:
인쇄된 결과로 돌아가 보겠습니다.
하지만 고양이 먹이를 먹고 싶다고 부모 클래스의 메서드를 변경하면 어떻게 될까요? 결과적으로 미미가 고양이 사료를 먹고 싶어 하는 것은 놀라운 일이 아닙니다.
하지만 문제가 발생합니다. 개 클래스를 만든 다음 eat 메서드를 호출하면 개도 고양이 사료를 먹어야 하나요? 이로 인해 문제가 발생하므로 하위 클래스에 eat 메서드를 작성할 수 있습니다.
class Animal{ public String name;//名字 public int age; public void eat() { System.out.println(this.name+"要吃饭!!!"); } } class Dog extends Animal{ public void dark() { System.out.println("汪汪汪!!!"); } public void eat() { System.out.println(this.name+"吃狗粮!!!"); } } class Cat extends Animal{ public void mew() { System.out.println("喵喵喵!!!"); } public void eat() { System.out.println(this.name+"吃猫粮!!!"); } } public class TestDemo1 { public static void main(String[] args) { //语法形式 : 父类 变量 = new 子类(); Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型 Animal animal2 = new Dog();//父类对象的引用 引用子类对象--->向上转型 animal1.name = "小猫";//访问父类属性 animal2.name = "小狗";//访问父类属性 animal1.eat(); animal2.eat(); // animal.mew();//访问子类特有的方法 } }
이때 우리가 원하는 효과를 얻을 수 있다는 것이 매우 명확해 졌다는 것을 알았습니다.
하지만 다시 생각해봐야 합니다. 왜 상위 클래스 대신 하위 클래스의 eat 메소드를 호출할까요?
동적 바인딩과 정적 바인딩동적 바인딩은 실제로 이때 발생합니다. 바이트코드 파일을 보고 Powershell 창을 열 수 있습니다.우리 모두는 프로그램을 실행하려면 먼저 컴파일하고 컴파일해야 한다는 것을 알고 있습니다. 컴파일할 때 Animal의 eat 메소드를 호출하고, 실행할 때 Cat의 메소드를 호출하는 것을 런타임 바인딩 또는 동적 바인딩이라고 합니다.
그래서 동적 바인딩이 있으므로 정적 바인딩도 있어야 합니다.
동적 바인딩은 컴파일 타임에 메서드를 호출하는 것이며, 호출할 최종 메서드는 런타임에 결정됩니다. 즉, 호출할 메서드가 런타임에 결정됩니다. 정적 바인딩은 컴파일 중에 호출할 메서드가 결정되었음을 의미합니다. 그 중에서 동적 바인딩의 가장 대표적인 것은 메소드 재작성입니다. 정적 바인딩의 가장 대표적인 것은 메서드 오버로딩입니다. 위의 메소드 epsilon=(´ο`*)))를 다시 살펴보겠습니다...이전 eat 메소드의 반환값, 매개변수 목록, 메소드 이름이 모두 동일한 이유는 무엇인가요? 한 번 보자.메서드 재작성
앞서 메소드 오버로딩에 대해 배웠습니다. 메소드 오버로딩은 메소드 이름이 동일하고 반환 값이 필요하지 않으며 매개변수 목록이 다르다는 것을 의미합니다. 오늘 배운 메소드 재작성은 반환 값도 같고, 메소드 이름도 같고, 매개변수 목록도 같다는 뜻인데, 메소드 재작성이라고 부르기도 합니다.
메서드 재작성에 대한 몇 가지 요구 사항이 있습니다. 메서드 재작성은 동일한 메소드 이름, 동일한 메소드 매개변수 목록 및 동일한 메소드 반환 값을 가져야 합니다.한 번의 클릭으로 다시 쓰기를 생성할 수도 있습니다
有几个注意事项:
不能重写被private修饰的方法。
不能重写被final修饰的方法。
子类的方法的访问权限一定要大于等于父类的访问权限。
重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成eat), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.
被static修饰的方法也不能被重写
总结方法重写的注意事项:
被private,final修饰的方法不能被重写。
被staitc修饰的方法也不能被重写。
@override 可以检查你重写的方法名是否正确,最好要加上。
方法重写一定满足方法名相同,参数列表相同,返回值相同。
对比方法重写与方法重载:
最后:重写不是进行在原来基础的修改,而是在原来基础上进行迭代和更新。
场景:画一个图形
class Shape{//创建一个图形类---->作为多种图形的父类 public int length;//图形的长 public int wide;//图形的宽 public int height;//图形的高 public void draw() { System.out.println("我要画一个图形!!!"); } } class rectangle extends Shape{//长方形 @Override public void draw() { System.out.println("我要画一个长方形!!!"); } } class square extends Shape{ @Override public void draw() { System.out.println("我要画一个正方形!!!"); } } class circular extends Shape{ @Override public void draw() { System.out.println("我要画一个圆形!!!"); } } public class TestDemo1 { public static void method(Shape shape) { shape.draw(); } public static void main(String[] args) { Shape shape1 = new circular(); Shape shape2 = new rectangle(); Shape shape3 = new square(); method(shape1); method(shape2); method(shape3); } }
创建一个Shape(父类),然后创建三个子类分别是square ,circular,rectangle,利用父类引用这三个子类,接着调用method方法。
这就是多态,不同的对象,调用同一个方法最后结果产生出不同的状态。
我们再来总结多态产生的条件:
要在继承体系下
子类要对父类的方法进行重写
通过父类的引用调用重写的方法
也就是 在继承体系下 进行向上转型 和 方法重写
优点:
能够降低代码的 "圈复杂度", 避免使用大量的 if - else
如果使用多态, 则不必写这么多的 if - else 分支语句, 代码更简单.
可扩展能力更强
缺点:
代码的运行效率降低
还有一个重要点就是不要在构造方法中调用重写方法
위 내용은 Java 객체지향 다형성 인스턴스 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!