本帖最后由 赵家阳 于 2012-9-11 14:55 编辑
//由于子类可以继承父类的内容,那么子父类出现后,类成员是如何变化的呢?
/*
* 类中成员包含三个部分:
* 1,变量
* 2,函数
* 3,构造函数
*
* 1,变量:如果子父类中出现了非私有的同名成员变量时,子类要访问本类中的变量:用this.
* 子类要访问父类中的同名变量,用super.
* super的使用和this的使用几乎一致
* this代表的是本类对象的引用
* super代表的是父类对象的引用
*
* 2,子父类中的函数:
* 当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容,
* 如同父类的函数被覆盖一样
* 这种情况是函数的另一个特性:重写(覆盖)
*
* 当子类继承了父类,此时沿袭了父类的功能到子类中,但是,子类虽具备该功能,功能的内容却和父类不一致,
* 这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容
*
* 覆盖:
* 子类覆盖父类,必须保证子类权限大于等于父类,才可以覆盖,否则编译失败
* 静态只能覆盖静态,(加载顺序问题)
*
* 记住:
* 重载:只看**同名函数**的参数列表
* 重写:子父类要一模一样,包括返回值类型
*/
//如下:
class Person
{
String name = "里斯";
int age = 20;
void showName() //权限默认不写时,权限介于public和private之间
{
System.out.println("这里是人类的名字:"+name);
}
public String getName() {
return name;
}
}
class Student extends Person //Student类时Person类的子类,Person类称为父类
{//此时,该类自动有了name,age属性
String name = "小明";
public void showName() //这里是覆盖,但是不会输出父类的内容
{
System.out.println(this.age); //此时,age还是指向了父类的age,为什么?因为子类没有定义,会默认指向父类的
System.out.println("这次打印的是学生的姓名:"+this.name);
System.out.println("还是学生的姓名:"+name); //由此可见,如果不用super标示,name默认是Student类的name
System.out.println("这个是谁的名字:"+super.name);
}
public String getName() //这是,子类必须和父类的类型一致
{
this.name = "Steven"; //不会错
return name;
}
}
public class 总结一 {
/**主函数入口
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s = new Student();
s.showName();
System.out.println(s.getName());
}
}
/* 3,子父类的构造函数
*
* 在对子类对象进行初始化时,父类的构造函数也会运行
* 那是因为子类的构造函数默认第一行有一条隐式的语句 super();
* super(); 会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
*
* 为什么子类一定要访问父类中的构造函数:
* 子类在用父类中的数据前,是否要查看一下该数据有没有初始化呢?那是必须的
* 因为:父类中的数据,子类可以直接获取,所以子类对象在建立时,需要查看父类是如何对这些数据进行初始化的
*
* 也就是说,父类会先于子类初始化,这样子类才能访问父类中的内容
*
* 所以子类在对象初始化时,要先访问一下父类中的构造函数,
* 如果要访问父类中指定的构造函数,可以通过手动的定义super()语句的方式来指定,如:super(5);
*
* 注意:super();语句一定要定义在子类构造函数的第一行,否则出错
*
* this();和super();都要放在第一行,所以二者不能同时出现在第一行,
* 但是他们为什么要出现在第一行? 因为初始化动作要先做
*
* 子类的实例化过程:(很重要)
* 结论:子类的所有的构造函数,默认都会访问父类中**空参数**的构造函数,因为子类的每一个构造函数内的第一行都有一句隐式super();
* 当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数
* 当然,子类的构造函数第一行也可由手动指定this();语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数
*/
//如下:
class Person
{
String name = "里斯";
int age = 20;
Person() //显示定义默认的构造函数,无参数
{
System.out.println("这里是父类默认的构造函数--Preson run");
}
Person(String name) //自定义的构造函数
{
System.out.println("自定义的父类构造函数,会输出姓名: "+name);
}
}
class Student extends Person
{
String name = "小明";
Student() //默认的构造函数
{
//如果不指定构造函数,就会访问默认的构造函数
super("张三"); //手动指定父类的构造函数,就不会访问默认的构造函数
System.out.println("这里是子类默认的构造函数--Student run");
}
Student(String name) //自定义的构造函数
{
this();
System.out.println("自定义的子类构造函数,会输出姓名: "+name);
}
Student(int age) //自定义的构造函数
{
//没有指定父类的构造函数,会访问默认的
System.out.println("自定义的子类构造函数,会输出年龄: "+age);
}
}
public class 总结一 {
/**主函数入口
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("第一次初始化对象:");
Student s = new Student();
System.out.println();
System.out.println("第二次初始化对象:");
Student s1 = new Student("往东");
System.out.println();
System.out.println("第三次初始化对象:");
Student sd = new Student("90");
}
} |
|