java面试题网站:www.javaoffers.com
对象 . 访问方法与对象所属的实例类型有关,访问属性与对象引用类 和 线程所在类(就是当前线程所执行的当前类文件)有关。
&对象访问方法:线程永远是从当前对象所属的实例类中找到对应的方法,如果不存在则会去父祖类中查找。
public class A{
say(){
system.out.println("this is A");
}
play(){
this.say();
}
}
public class B extends A{
}
public class C Extends A{
say(){
system.out.println("this is C");
}
}
public class TestFunction(){
@Test
public void test1(){
A a = new A();
B b = new B();
C c = new C();
a.say(); //先从对象所属的类A中找方法,存在执行say()输出: this is A
b.say(); //先从对象所属的类B中找方法, 发现没有该方法,那么会逐步向父类中查找,直到找到停止,否者会报方法找不到,开始想父类A中找,发现存此调用的方法,开始执行
c.say(); //先从对象所属C类中找方法,发现存在调用的方法则执行say方法,不会去父类中查找。
c.play();//先从对象所属C类中找方法,发现没有,去父类A中查找,发现调用的方法则执行play(),在play中存在this.say()方法,this代表C对象所属C类,则先从类中查找方法,发现存在say(),则执行。
}
}
总结: 当一个对象方法一个方法的时候,永远是先从对象所属的实例类开始查找对应的方法。
&访问属性与对象引用类和线程所在类(就是当前线程所执行的当前类文件)有关
通常访问属性是比较复杂的。先看下面的例子。
package com.jvm.others.others;
import org.junit.Test;
/**方法与属性的差别
* @author 曹明杰
*
*/
public class FunctionAndAttr {
@Test
public void test(){
A a = new A();
B b = new B();
System.out.println(a.dog); //输出"dog"
System.out.println(b.dog);; //输出 "dog2"
A a2 = b;
System.out.println(a2.dog); //输出"dog"
b.say();//输出"dog"
a2.say();//输出dog
}
}
class A {
String dog = "dog";
void say(){
System.out.println(this.dog);
}
}
class B extends A{
String dog = "dog2";
}
总结:当对象变量直接使用点.属性的时候进行访问属性值时,是从变量引用类开始查找如果找不到并会向父祖类中进行查找(向父类中的父类依次类推知道所有父类都找不到则会报错),当使用this.属性的时候,是从当前的线程所在的执行类开始查找。并会向父祖类中进行查找。