2.对虚拟方法调用的理解: 虚拟方法调用 (Virtual Method Invocation) 正常的方法调用 Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo(); 虚拟方法调用 ( 多态情况下 ) 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父 类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法 确定的。 Person e = new Student(); e.getInfo(); // 调用 Student 类的 getInfo() 方法 编译时类型和运行时类型 编译时 e 为 Person 类型,而方法的调用是在运行时确定的,所以调用的是 Student 类 的 getInfo() 方法。 —— 动态绑定
3.多态属于运行时行为还是编译时行为?怎么证明?
答:多态是运行时行为,只有运行时才能确定实例化对象
举例如下:
import java.util.Random;
//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal {
protected void eat() {
System.out.println("animal eat food");
}
}
class Cat extends Animal {
protected void eat() {
System.out.println("cat eat fish");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("Dog eat bone");
}
}
class Sheep extends Animal {
public void eat() {
System.out.println("Sheep eat grass");
}
}
public class InterviewTest {
public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}
}
public static void main(String[] args) {
int key = new Random().nextInt(3);
System.out.println(key);
Animal animal = getInstance(key);
animal.eat();
}
}
在没有执行之前,没有办法确认具体实例化了哪个对象
只有执行以后才能确定实例化的对象
4.重载和重写的区别? 4.1定义上重载: 同类同名不同参(参数类型,参数数量,参数顺序)
重写:子父类的子类中,对父类同名同参方法的方法体重写
4.2在机制上重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不
同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了
不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类
和子类的,即子类可以重载父类的同名不同参数的方法。
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,
这称为“早绑定”或“静态绑定”;
5.向下转型与instanceof关键字 5.1向下转型:把父类强制转换成子类对象 5.2instanceof关键字:a instanceof A:判断a是否是A类的一个实例
import java.util.Date;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
/
if(p2 instanceof Woman){
Woman w1 = (Woman)p2;
w1.goShopping();
System.out.println("******Woman******");
}
if(p2 instanceof Man){
Man m2 = (Man)p2;
m2.earnMoney();
System.out.println("******Man******");
}
if(p2 instanceof Person){
System.out.println("******Person******");
}
if(p2 instanceof Object){
System.out.println("******Object******");
}
// if(p2 instanceof String){
//
// }
//练习:
//问题一:编译时通过,运行时不通过
//举例一:
// Person p3 = new Woman();
// Man m3 = (Man)p3;
//举例二:
// Person p4 = new Person();
// Man m4 = (Man)p4;
//问题二:编译通过,运行时也通过
// Object obj = new Woman();
// Person p = (Person)obj;
//问题三:编译不通过
// Man m5 = new Woman();
// String str = new Date();
// Object o = new Date();
// String str1 = (String)o;
}
}
其中Person类(父类)
package com.atguigu.java;
public class Person {
String name;
int age;
int id = 1001;
public void eat(){
System.out.println("人:吃饭");
}
public void walk(){
System.out.println("人:走路");
}
}
Man类(Person类的子类1)
package com.atguigu.java;
public class Man extends Person{
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
Woman类(Person类子类2)
package com.atguigu.java;
public class Woman extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println("女人喜欢购物");
}
public void eat(){
System.out.println("女人少吃,为了减肥");
}
public void walk(){
System.out.println("女人窈窕的走路");
}
}
6.对多态性理解的测试题
package MultiTest;
class SuperClass{
int id = 10;
public void show() {
System.out.println(this.id);
}
}
class SubClass extends SuperClass{
int id = 20;
public void show() {
System.out.println(this.id);
}
}
public class Test1 {
public static void main(String[] args) {
SubClass s = new SubClass();
System.out.println(s.id);
s.show();
SuperClass su = s;//多态
System.out.println(su.id);
System.out.println(su == s);
su.show();
}
}
最后的答案为:
20/20/10/true/20



