자바의 다형성
다형성은 다른 형태 또는 형태의 다수의 동일한 동작을하는 기능입니다.
다형성은 표현의 많은 형태의 목적이다.
실제로, 이러한 우리는이 작업에 F1 키를 누를 때 :
- 플래시 팝업 인터페이스에서 현재 3 도움말 문서 AS 경우;
- 현재는 배출 워드 워드의 도움말에있는 경우;
- 팝업 윈도우에서 Windows 도움말 및 지원이다.
다른 개체에 동일한 이벤트는 다른 결과를 생성합니다.
다형성의 존재에 대한 세 가지 필요한 조건 :
- 상속
- 고쳐 쓰기
- 서브 클래스 객체에 대한 부모 참조
예를 들면 :
Parent p = new Child();
존재하는 경우, 다시 동일한 방법으로 서브 클래스를 호출 다형성 방법을 사용하는 방법을 호출 할 때, 제가 상위 클래스의 방법이고, 그렇지 않은 경우, 컴파일러 에러 여부를 확인한다.
다중 상태 혜택 : 당신은 프로그램에게 좋은 확장 할 수 있으며, 클래스의 모든 일반적인 개체를 처리 할 수 있습니다.
다음 프리젠 테이션은 다중 상태 인스턴스 세부 사항이며, 참고 참조 :
public class Test { public static void main(String[] args) { show(new Cat()); // 以 Cat 对象调用 show 方法 show(new Dog()); // 以 Dog 对象调用 show 方法 Animal a = new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eat Cat c = (Cat)a; // 向下转型 c.work(); // 调用的是 Cat 的 catchMouse } public static void show(Animal a) { a.eat(); // 类型判断 if (a instanceof Cat) { // 猫做的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a; c.work(); } } } abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); } }
위의 프로그램은 출력은 다음과 같습니다
吃鱼 抓老鼠 吃骨头 看家 吃鱼 抓老鼠
가상 방법
집단 소송을 설계하는 것이 다형성에 미치는 영향의 오버라이드 (override)되는 메소드가있을 때 우리는 자바에 소개합니다.
우리는 이미 서브 클래스가 상위 클래스를 대체 할 수있는 대체 방법을 논의했다.
서브 클래스 객체가 오버라이드 (override) 된 메소드를 호출 할 때, 서브 클래스의 방법보다는 부모 클래스 오버라이드 (override) 메소드를 호출합니다.
부모 클래스의 메소드가 오버라이드 (override) 호출하려면 super 키워드를 사용해야합니다.
/* 文件名 : Employee.java */ public class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Employee 构造函数"); this.name = name; this.address = address; this.number = number; } public void mailCheck() { System.out.println("邮寄支票给: " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } }
다음 클래스를 가정하면 Employee 클래스를 상속 :
/* 文件名 : Salary.java */ /* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; // 全年工资 public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Salary 类的 mailCheck 方法 "); System.out.println("邮寄支票给:" + getName() + " ,工资为:" + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("计算工资,付给:" + getName()); return salary/52; } }
이제 우리는 다음 코드의 출력을 제공하려고 읽기 :
/* 文件名 : VirtualDemo.java */ public class VirtualDemo { public static void main(String [] args) { Salary s = new Salary("员工 A", "北京", 3, 3600.00); Employee e = new Salary("员工 B", "上海", 2, 2400.00); System.out.println("使用 Salary 的引用调用 mailCheck -- "); s.mailCheck(); System.out.println("\n使用 Employee 的引用调用 mailCheck--"); e.mailCheck(); } }
다음과 같은 결과를 컴파일 위의 예는 다음과 같습니다
Employee 构造函数 Employee 构造函数 使用 Salary 的引用调用 mailCheck -- Salary 类的 mailCheck 方法 邮寄支票给:员工 A ,工资为:3600.0 使用 Employee 的引用调用 mailCheck-- Salary 类的 mailCheck 方法 邮寄支票给:员工 B ,工资为:2400.0
분석 예
예, 두 개체 급여를 인스턴스화 : 급여 이용의 참조, 다른 사용 직원 참조 전자.
() s.mailCheck를 호출 할 때, 컴파일러는 급여 클래스의 컴파일 시간 ()에서 MAILCHECK을 발견, 구현 프로세스 JVM은 MAILCHECK 급여 클래스 ()를 호출합니다.
s.mailCheck ()를 호출 할 때, 자바 가상 머신 (JVM)의 급여 클래스 MAILCHECK () 메서드를 호출합니다.
전자는 직원 참조, 그래서 컴파일러는 Employee 클래스를 이동합니다 발신자의 전자 MAILCHECK () 메소드는 MAILCHECK () 메소드를 보이기 때문에.
컴파일시에 컴파일러는 문을 확인하기 위해 Employee 클래스 MAILCHECK () 메소드를 사용하지만 런타임에 자바 가상 머신 (JVM)은 급여 클래스 MAILCHECK () 메서드 호출됩니다.
상기 과정을 통해 그 가상 메소드 호출 가상 메소드 호출을 호출한다.
어떤 데이터 유형 참조 변수를 컴파일 할 때 모든 Java 메소드에 관계없이 소스 코드, 따라서 런타임에 호출 방법을 대체 할 수 있습니다,이 방식으로 동작 할 수 있습니다.