/*
类变量:又叫静态变量,这种变量属于类,通过类名就可以访问类变量。
实例变量:属于类的实例即对象,通过对象可以访问实例变量,但是不能通过类名访问实例变量。
静态方法:方法属于类,通过对象访问实例方法,不能通过类名访问实例方法。
隐藏:B隐藏了A的变量或者方法,那么,B不能访问A被隐藏的变量或方法,但是,将B转换成A后,可以访问A被隐藏的变量或方法。
覆盖:B覆盖了A的变量或者方法,那么,B不能够访问A被覆盖的变量或方法,将B转换成A后,同样不能访问A被覆盖的变量或方法。
Java中方法和变量在继承时的覆盖与隐藏规则如下:
父类的实例变量和类变量能被子类的同名变量隐藏。
父类的静态方法被子类的同名静态方法隐藏。
父类的实例方法被子类的同名实例方法覆盖。
不能用子类的静态方法隐藏父类中同样标识的实例方法,否则编译器将会报错。
不能用子类的实例方法覆盖父类中同样标识的静态方法,否则编译器会报错。
最终方法(带关键字final的方法)不能被覆盖。
变量只会被隐藏,不会被覆盖,无论她是实例变量还是静态变量。而且,子类的静态变量可以隐藏父类的实例变量,子类的实例变量可以隐藏父类的静态变量。
*/
public class AccessMethod
{
public static void main(String[] args)
{
//先测试继承时变量的覆盖于隐藏问题
System.out.println("在继承关系中,同名变量的覆盖与隐藏的执行内容如下:");
ChildClass child = new ChildClass();
System.out.println("\t创建了ChildClass对象,ChildClass的属性信息如下:");
System.out.println("name:" + child.name + "; age:" + child.age + "; var:" + child.classVar);
//将ChildClass类型转换成parentClass对象
ParentClass parent = child;
System.out.println("将创建的ChildClass对象赋值给ParentClass对象,其属性信息如下:");
System.out.println("name:" + parent.name + "; age:" + parent.age + "; var:" + parent.classVar);
System.out.println("子类可以访问父类被隐藏的实例变量name:" + child.getParentName());
System.out.println("子类可以访问父类被隐藏的实例变量age:" + child.getParentAge());
System.out.println("子类可以访问父类被隐藏的静态变量var:" + child.getParentVar());
System.out.println("\n<>------------------>>\n");
//再测试继承时方法的覆盖与隐藏问题
System.out.println("在继承关系中,同名方法的覆盖与隐藏的执行内容如下:");
child.getName();//实例方法
child.getClassVar();//静态方法
parent.getName();//实例方法
parent.getClassVar();//静态方法
}
}
class ParentClass
{
public static String classVar = "父类的字符串类变量";
public static int age = 50;//类变量,ParentClass年龄
public String name = "ParentClass";//实例变量,ParentClass的名字
//静态方法,获取ParentClass的类别
public static String getClassVar()
{
//静态方法中操作的只能是类变量,静态变量
System.out.println("ParentClass的getClassVar()方法被调用!");
return classVar;
}
//静态方法,获取ParentClass的年龄
public static int getAge()
{
//静态方法中操作的只能是类变量,静态变量
System.out.println("ParentClass的getAge)方法被调用!");
return age;
}
//实例方法,获取ParentClass的名字
public String getName()
{
//实例方法中操作的可以是实例变量,也可以是类变量
System.out.println("ParentClass的getName()方法被调用了!");
return this.name;
}
//final方法,将ParentClass的年龄减1
public final int getPreviousAge()
{
System.out.println("ParentClass的getPreviousAge()方法被调用!");
return --age;
}
}
class ChildClass extends ParentClass
{
public static String classVar = "子类的字符串类变量";
public int age = 25;//实例变量,ChildClass的年龄,在ParentClass类是static的
public String name = "ChildClass";//实例变量,ChildClass的名字
//静态方法,获取ChildClass的类别
public static String getClassVar()
{
//静态方法中操作的只能是类变量,静态变量
System.out.println("ChildClass的getClassVar()方法被调用!");
return classVar;
}
//静态方法,获取父类的类别
public static String getParentVar()
{
//通过类名加“.”访问父类被隐藏的类变量
return ParentClass.classVar;
}
//实例方法,获取ChildClass的名字
public String getName()
{
System.out.println("ChildClass的getName()方法被调用!");
return this.name;
}
//实例方法,获取父类的名字
public String getParentName()
{
//通过super关键字父类中被隐藏的实例变量
return super.name;
}
//实例方法,获取父类的年龄
public int getParentAge()
{
return ParentClass.age;
}
}
/*
1.同名的实例方法被覆盖,同名的静态方法被隐藏。
Child类的getName()实例方法覆盖了Parent类的getName()实例方法;
Child类的getClassVar()静态方法隐藏了Parent类的getClassVar()静态方法。
2.隐藏和覆盖的区别在于:子类对象转换成父类对象后,能够访问父类被隐藏
的变量和方法,而不能访问父类被覆盖的变量和方法。
把child对象转换成Parent类的对象parent时,不能访问parent的getName()实例方法;
把child对象转换成Parent类的对象parent后,能够访问Parent的getClassVar()静态方法。
3.子类若需要访问父类中被隐藏的实例变量,需要使用super关键字。
Child类的getParentName()方法中就使用super.name访问Parent类的name实例变量。
4.子类若需要访问父类中被隐藏的类变量,需要使用父类的名字加点“.”来访问。
Child类的getParentAge()方法使用了ParentClass.age访问Parent类的age静态变量。
*/