22
33/*
44 * 如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为final。用final修饰的类不能被继承
5+ * 在OOP的术语中,我们把Student称为超类(super class),父类(parent class),基类(base class),把SuperDemo称为子类(subclass),扩展类(extended class)。
6+ * 继承有个特点,就是子类无法访问父类的private字段或者private方法。
57 */
68public class SuperDemo extends Student {
79 public final String strss ;//这里不初始化赋值,变量会报错,解决这个报错的办法是在构造方法里面给strss初始化赋值
810 public final String name = "用final修饰的字段在初始化后不能被修改" ;
11+
12+ public final static String strStatic = "" ;//用final static修饰的变量,必须直接初始化,否则编译报错
913
10- //用final static修饰的变量,必须直接初始化,否则编译报错
11- public final static String strStatic = "" ;//这里不初始化赋值,变量会报错,解决这个报错的办法是在构造方法里面给strss初始化赋值
12-
14+ private String testStr ;
15+ public String testStr2 = "调用的是子类的SuperDemo属性:testStr2" ;
16+ public String stuName ;// 注意:子类自动获得了父类的所有字段,严禁定义与父类重名的字段!
17+
1318 public SuperDemo (){
19+ super ("Student类的stuName" );
1420 strss = "" ;//这里不给strss初始化赋值,编译会报错
21+ this .stuName = "子类SuperDemo的stuName" ;
1522 }
1623 public SuperDemo (String name ) {
24+ super (name );
1725 strss = "" ;//这里不给strss初始化赋值,编译一样会报错
18- }
19-
20- public static void main (String [] args ) {
21- SuperDemo .testStatic ();//静态方法也可以被继承
22- SuperDemo sd = new SuperDemo ();
23- sd .superDemo ();
24- //sd.name="121";这里会报错,因为name,是用final修饰的,并且JVM会针对final修饰的字段做优化,详情参考PerfmaDemo类.
25- //并且用final修饰的属性,也不能提供set方法
26- System .out .println ();
26+ this .stuName = "子类SuperDemo的stuName" ;
2727 }
2828
2929 public void superDemo () {
@@ -42,6 +42,68 @@ public String getName() {
4242 }
4343
4444// public void setName(String name){
45- // this.name = name;
45+ // this.name = name; name是用final修改的,不能重新赋值了
4646// }
47+
48+
49+ public String getTestStr () {
50+ return testStr ;
51+ }
52+ public void setTestStr (String testStr ) {
53+ this .testStr = "调用的是子类的SuperDemo的testStr属性:" + testStr ;
54+ }
55+
56+ public void setServices (String services ) {
57+ this .services = services ;
58+ }
59+
60+ public static void main (String [] args ) {
61+ SuperDemo .testStatic ();//静态方法也可以被继承
62+ SuperDemo sd = new SuperDemo ("test" );
63+ sd .superDemo ();
64+ System .out .println ();
65+ System .out .println ("子类的对象地址" + sd );
66+ System .out .println ("这里输出的是子类的stuName:-》" + sd .stuName );
67+ System .out .println ("这里获取的是父类的的stuName属性因为调的是父类getStuName的方法,所以要用父类的stuName属性:-->" + sd .getStuName ());
68+
69+ //sd.name="121";这里会报错,因为name,是用final修饰的,并且JVM会针对final修饰的字段做优化,详情参考PerfmaDemo类.
70+ //并且用final修饰的属性,也不能提供set方法
71+ System .out .println ();
72+
73+ sd .setServices ("子类set父类get" );
74+
75+ /*
76+ * 这里实际上设置的是父类的属性services,然后设置为被子类继承了,所以sd.services
77+ * 能取到值,你可以反编译看一下setServices这个方法
78+ */
79+ System .out .println ("子类的services属性:-->" + sd .services );
80+ sd .printServices ();
81+
82+ System .out .println ();
83+ System .out .println ("***********************************" );
84+
85+ /*
86+ * Student stu = new SuperDemo();
87+ * 这是因为SuperDemo继承自Student,因此,它拥有Student的全部功能。Student类型的变量,如果指向SuperDemo类型的实例,对它进行操作,是没有问题的!
88+ * 这种把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)。
89+ * 向上转型实际上是把一个子类型安全地变为更加抽象的父类型:
90+ * 注意到继承树是SuperDemo > Student > Object,所以,可以把SuperDemo类型转型为Student,或者更高层次的Object。
91+ * 向下转型
92+ * 和向上转型相反,如果把一个父类类型强制转型为子类类型,就是向下转型(downcasting)。例如:
93+ */
94+ Student stu = new SuperDemo ();
95+ stu .superDemo ();
96+
97+ stu .setTestStr ("测试" );
98+ System .out .println ("这里调用的是子类的getTestStr,所以打印的是子类的testStr属性->>:" + stu .getTestStr ());//这里调用的子类的
99+ /*
100+ * 注意如果通过父类.属性调用,那么调用的就是父类的属性,
101+ * 如果通过get方法调用那调用的就是子类的属性
102+ */
103+ System .out .println ("……父类……->" + stu .testStr2 );
104+ System .out .println ();
105+ System .out .println ("子类的对象地址" + stu );
106+ System .out .println ("这里输出的是父类的:-》" + stu .stuName );
107+ System .out .println ("这里获取的是谁的属性:因为调用的是父类的getStuName方法->" + stu .getStuName ());
108+ }
47109}
0 commit comments