关于父类与子类在属性和方法调用的代码
- /**
- * 方法重写
- */
- package org.sean.module03;
- /**
- * 类变量指的是属于类,通过类名就有可以访问的变量
- *
- * 实例变量指的是属于类的实例,通过对象可以访问实例变量,但是通过类名不能访问实例变量
- *
- * 同样,静态方法属于一个类,通过类名就可以访问静态方法,而实例方法属于对象,通过对象可以访问
- *
- * 所谓隐藏:子类隐藏父类的属性和静态方法,通过子类对象,不能访问父类隐藏了的属性和静态方法(属性和静态方法不存在多态性)
- *
- * 但是将子类对象转换为父类对象之后,可以访问父类中被隐藏的属性和静态方法
- *
- * 所谓覆盖(重写): 子类能够覆盖父类的实例方法,通过子类对象,不能访问父类被覆盖了的实例方法
- *
- * 将子类转换为父类对象后,也不能访问父类中被覆盖的实例方法。
- *
- * 结论:属性和静态方法只能被隐藏,实例方法只能被覆盖(重写)
- *
- * @author 不落的太阳(Sean Yang)
- */
- class Parent2 {
- // 类变量,Parent的类别
- public static String kind = "org.sean.module03.CoverAndHide.Parent";
- // 类变量,Parent的年龄
- public static int age = 50;
- // 实例变量,Parent的名称
- public String name = "Parent";
- /** 静态方法,获得Parent的类别 */
- public static String getKind() {
- System.out.println("parent getKind() method called");
- return kind;
- }
- /** 静态方法,获得Parent的年龄 */
- public static int getAge() {
- System.out.println("parent getAge() method called");
- return age;
- }
- /** 实例方法,获得Parent的名称 */
- public String getName() {
- System.out.println("parent getName() method called");
- return this.name;
- }
- }
- class Child2 extends Parent2 {
- // 类变量,Child的类别
- public static String kind = "org.sean.module03.CoverAndHide.Child";
- // 类变量,Child的年龄
- public static int age = 25;
- // 实例变量,Child的名称
- public String name = "child";
- /** 静态方法,获得Child的类别 */
- public static String getKind() {
- System.out.println("child getKind() method called");
- return kind;
- }
- /** 静态方法,获得Child的年龄 */
- public static int getAge() {
- System.out.println("child getAge() method called");
- return age;
- }
- /** 实例方法,获得Child的名称 */
- public String getName() {
- System.out.println("child getName() method called");
- return this.name;
- }
- /** 实例方法,获得Parent的名称 */
- public String getParentName() {
- return super.name;
- }
- /** 静态方法,获得Parent的类别 */
- public static String getParentKind() {
- return Parent2.kind;
- }
- }
- public class CoverAndHide {
- @SuppressWarnings("static-access")
- public static void main(String[] args) {
- Child2 child = new Child2();
- System.out.println("child name is " + child.name + ", child age is "
- + child.age + " ,kind is " + child.kind);// 此处得到都是Child类的变量值
- /** 将Child类型转换为Parent类型,即多态情况 */
- // Parent2 parent = child;
- Parent2 parent = new Child2();
- System.out.println("转换为Parent之后的name is " + parent.name + ", age is "
- + parent.age + " ,kind is " + parent.kind);
- /**
- * 结论:
- *
- * 父类的实例变量和类变量能被子类的同名变量遮盖(隐藏),将子类对象转换为父类对象后,可以访问父类对象的实例变量和类变量
- *
- * 在子类中如果需要访问父类中被隐藏的实例变量,需要使用"super.属性名"
- *
- * 在子类中如果需要访问父类中被隐藏的类变量,需要使用"父类名.属性名"
- */
- System.out.println("子类访问父类被隐藏的实例变量:" + child.getParentName());
- System.out.println("子类访问父类被隐藏的类变量:" + child.getParentKind());
- /** 继承时方法的覆盖与隐藏问题 */
- child.getName();
- child.getKind();
- parent.getName();
- parent.getKind();
- /**
- * 结论:
- *
- * 父类的静态方法被子类的同名静态方法隐藏,而父类的实例方法被子类的实例方法覆盖(重写)
- *
- * 将子类转换为父类对象后(或者多态),可以访问父类的静态方法,但不能访问父类的实例方法
- */
- }
- }
/**
* 方法重写
*/
package org.sean.module03;
/**
* 类变量指的是属于类,通过类名就有可以访问的变量
*
* 实例变量指的是属于类的实例,通过对象可以访问实例变量,但是通过类名不能访问实例变量
*
* 同样,静态方法属于一个类,通过类名就可以访问静态方法,而实例方法属于对象,通过对象可以访问
*
* 所谓隐藏:子类隐藏父类的属性和静态方法,通过子类对象,不能访问父类隐藏了的属性和静态方法(属性和静态方法不存在多态性)
*
* 但是将子类对象转换为父类对象之后,可以访问父类中被隐藏的属性和静态方法
*
* 所谓覆盖(重写): 子类能够覆盖父类的实例方法,通过子类对象,不能访问父类被覆盖了的实例方法
*
* 将子类转换为父类对象后,也不能访问父类中被覆盖的实例方法。
*
* 结论:属性和静态方法只能被隐藏,实例方法只能被覆盖(重写)
*
* @author 不落的太阳(Sean Yang)
*/
class Parent2 {
// 类变量,Parent的类别
public static String kind = "org.sean.module03.CoverAndHide.Parent";
// 类变量,Parent的年龄
public static int age = 50;
// 实例变量,Parent的名称
public String name = "Parent";
/** 静态方法,获得Parent的类别 */
public static String getKind() {
System.out.println("parent getKind() method called");
return kind;
}
/** 静态方法,获得Parent的年龄 */
public static int getAge() {
System.out.println("parent getAge() method called");
return age;
}
/** 实例方法,获得Parent的名称 */
public String getName() {
System.out.println("parent getName() method called");
return this.name;
}
}
class Child2 extends Parent2 {
// 类变量,Child的类别
public static String kind = "org.sean.module03.CoverAndHide.Child";
// 类变量,Child的年龄
public static int age = 25;
// 实例变量,Child的名称
public String name = "child";
/** 静态方法,获得Child的类别 */
public static String getKind() {
System.out.println("child getKind() method called");
return kind;
}
/** 静态方法,获得Child的年龄 */
public static int getAge() {
System.out.println("child getAge() method called");
return age;
}
/** 实例方法,获得Child的名称 */
public String getName() {
System.out.println("child getName() method called");
return this.name;
}
/** 实例方法,获得Parent的名称 */
public String getParentName() {
return super.name;
}
/** 静态方法,获得Parent的类别 */
public static String getParentKind() {
return Parent2.kind;
}
}
public class CoverAndHide {
@SuppressWarnings("static-access")
public static void main(String[] args) {
Child2 child = new Child2();
System.out.println("child name is " + child.name + ", child age is "
+ child.age + " ,kind is " + child.kind);// 此处得到都是Child类的变量值
/** 将Child类型转换为Parent类型,即多态情况 */
// Parent2 parent = child;
Parent2 parent = new Child2();
System.out.println("转换为Parent之后的name is " + parent.name + ", age is "
+ parent.age + " ,kind is " + parent.kind);
/**
* 结论:
*
* 父类的实例变量和类变量能被子类的同名变量遮盖(隐藏),将子类对象转换为父类对象后,可以访问父类对象的实例变量和类变量
*
* 在子类中如果需要访问父类中被隐藏的实例变量,需要使用"super.属性名"
*
* 在子类中如果需要访问父类中被隐藏的类变量,需要使用"父类名.属性名"
*/
System.out.println("子类访问父类被隐藏的实例变量:" + child.getParentName());
System.out.println("子类访问父类被隐藏的类变量:" + child.getParentKind());
/** 继承时方法的覆盖与隐藏问题 */
child.getName();
child.getKind();
parent.getName();
parent.getKind();
/**
* 结论:
*
* 父类的静态方法被子类的同名静态方法隐藏,而父类的实例方法被子类的实例方法覆盖(重写)
*
* 将子类转换为父类对象后(或者多态),可以访问父类的静态方法,但不能访问父类的实例方法
*/
}
}
关于父类和子类加载顺序的代码
- /**
- * 类的加载顺序
- */
- package org.sean.module03;
- /**
- * 父类的静态代码块--->子类的静态代码块--->父类的初始化块 --->父类的构造方法 --->子类的初始化块--->子类的构造方法
- *
- * 对于静态的部分,按照声明的先后顺序进行加载
- *
- * @author 不落的太阳(Sean Yang)
- */
- class Parent1 {
- @SuppressWarnings("unused")
- private int x = 50;
- static {
- System.out.println("parent static block");
- }
- @SuppressWarnings("unused")
- private static int sx = getNext(99);
- {
- System.out.println("parant init block");
- }
- public Parent1() {
- System.out.println("parent constructor");
- }
- public static int getNext(int base) {
- System.out.println("static parameter initialized");
- return ++base;
- }
- }
- class Child1 extends Parent1 {
- static {
- System.out.println("child static block");
- }
- {
- System.out.println("child init block");
- }
- public Child1() {
- System.out.println("child constructor");
- }
- }
- public class LoadingOrder {
- public static void main(String[] args) {
- @SuppressWarnings("unused")
- Child1 child = new Child1();
- }
- }
/**
* 类的加载顺序
*/
package org.sean.module03;
/**
* 父类的静态代码块--->子类的静态代码块--->父类的初始化块 --->父类的构造方法 --->子类的初始化块--->子类的构造方法
*
* 对于静态的部分,按照声明的先后顺序进行加载
*
* @author 不落的太阳(Sean Yang)
*/
class Parent1 {
@SuppressWarnings("unused")
private int x = 50;
static {
System.out.println("parent static block");
}
@SuppressWarnings("unused")
private static int sx = getNext(99);
{
System.out.println("parant init block");
}
public Parent1() {
System.out.println("parent constructor");
}
public static int getNext(int base) {
System.out.println("static parameter initialized");
return ++base;
}
}
class Child1 extends Parent1 {
static {
System.out.println("child static block");
}
{
System.out.println("child init block");
}
public Child1() {
System.out.println("child constructor");
}
}
public class LoadingOrder {
public static void main(String[] args) {
@SuppressWarnings("unused")
Child1 child = new Child1();
}
}