我做的测试 public class Test extends A{ public void test(){ this.a = "Test的a"; super.a = "父类A的a"; System.out.println(this.a);
A.Inner in = new A().new Inner(); System.out.println(in.b); Test.Inner testIn = new Test().new Inner(); System.out.println(testIn.b); testIn.b = "----"; System.out.println(testIn.b); System.out.println(in.b); }
public static void main(String[] args) { Test t = new Test(); t.test(); } } class A{ String a; class Inner{ String b = "=="; } }结果: 父类A的a == == ---- ==
只是从规范分析上讲啊。 这三个都是不继承的。 因为它们没有声明为protected及以上作用域,无声明的情况下默认为(default),高于private低于protected,仅能同包访问 虽然不继承,但是在你的这种写法里面,A和B两个class是在同一个包下,所以B对于A的属性、方法都具有访问的权限 但这仅仅规范逻辑,实际上取决于编译器的实现方式我猜测(瞎猜)在写new B().fun1()的时候,实际上是构造了Object又构造了A又构造了B,然后把这三个玩意用栈的形式堆叠起来。 B是最后构建的,最后入栈所以最先出栈。 访问的时候,先访问B,发现B里面没这个玩意,那就访问B下面的A,发现居然找到了!虽然原则上不应该,但它就是找到了,于是它抛弃原则,访问了这个玩意。但是……方法存于栈中,属性却不是…… 总之属性更麻烦一些,像你的这种情况,由于a是default的,所以它应该不能被继承,但是访问器能访问到 见如下代码: public class TestA { public static void main(String[] args) throws Exception { AA a = new AAA(); System.out.println(AA.class.getField("a").get(a)); System.out.println(AAA.class.getField("a").get(a)); }} class AA { public int a = 0; }class AAA extends AA {
public int a = 1; }// 0 // 1这两个都是public的属性,通过AA.class和通过AAA.class去访问同一个对象,得到的却是两个值 这说明,属性天生就是不适用于继承关系的,即使是public的属性,也不能继承和覆盖,仅仅是子类能够通过作用域被访问到父类而已综上,继承原则是设计上的原则,实际上编译器只是遵守public、protected、(default)、private四个作用域。 属性和方法在存储方式上的不同决定了,子类的属性不能覆盖父类的属性,子类的方法可以覆盖父类的方法。 所以为了安全,继承的时候,用方法而不是属性。
2、方法与内部类也一样,都会被继承
public class Test extends A{
public void test(){
this.a = "Test的a";
super.a = "父类A的a";
System.out.println(this.a);
A.Inner in = new A().new Inner();
System.out.println(in.b);
Test.Inner testIn = new Test().new Inner();
System.out.println(testIn.b);
testIn.b = "----";
System.out.println(testIn.b);
System.out.println(in.b);
}
public static void main(String[] args) {
Test t = new Test();
t.test();
}
}
class A{
String a;
class Inner{
String b = "==";
}
}结果:
父类A的a
==
==
----
==
这三个都是不继承的。
因为它们没有声明为protected及以上作用域,无声明的情况下默认为(default),高于private低于protected,仅能同包访问
虽然不继承,但是在你的这种写法里面,A和B两个class是在同一个包下,所以B对于A的属性、方法都具有访问的权限
但这仅仅规范逻辑,实际上取决于编译器的实现方式我猜测(瞎猜)在写new B().fun1()的时候,实际上是构造了Object又构造了A又构造了B,然后把这三个玩意用栈的形式堆叠起来。
B是最后构建的,最后入栈所以最先出栈。
访问的时候,先访问B,发现B里面没这个玩意,那就访问B下面的A,发现居然找到了!虽然原则上不应该,但它就是找到了,于是它抛弃原则,访问了这个玩意。但是……方法存于栈中,属性却不是……
总之属性更麻烦一些,像你的这种情况,由于a是default的,所以它应该不能被继承,但是访问器能访问到
见如下代码:
public class TestA { public static void main(String[] args) throws Exception {
AA a = new AAA();
System.out.println(AA.class.getField("a").get(a));
System.out.println(AAA.class.getField("a").get(a));
}}
class AA {
public int a = 0;
}class AAA extends AA {
public int a = 1;
}// 0
// 1这两个都是public的属性,通过AA.class和通过AAA.class去访问同一个对象,得到的却是两个值
这说明,属性天生就是不适用于继承关系的,即使是public的属性,也不能继承和覆盖,仅仅是子类能够通过作用域被访问到父类而已综上,继承原则是设计上的原则,实际上编译器只是遵守public、protected、(default)、private四个作用域。
属性和方法在存储方式上的不同决定了,子类的属性不能覆盖父类的属性,子类的方法可以覆盖父类的方法。
所以为了安全,继承的时候,用方法而不是属性。