JAVA基类和派生类_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > JAVA基类和派生类

JAVA基类和派生类

 2014/5/22 18:57:25  chokee  程序员俱乐部  我要评论(0)
  • 摘要:JAVA基类和派生类从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域。但继承并不仅仅是类的复用。当创建了一个派生类的对象时,该类包含了一个基类的子对象。这个子对象和你用基类直接创建的对象没有什么两样。二者的区别在于,后者来自于外部,而基类的子对象来自于派生类对象的内部。对基类的子对象初始化时至关重要的,而且也只有一种方法来保证这一点,那就是在派生类的构造器中调用基类的构造器,而基类的构造器具有执行基类初始化所需的所有能力和知识。在无参构造器时
  • 标签:Java
JAVA基类和派生类


  从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 。但继承并不仅仅是类的复用。当创建了一个派生类的对象时,该类包含了一个基类的子对象。这个子对象和你用基类直接创建的对象没有什么两样。二者的区别在于,后者来自于外部,而基类的子对象来自于派生类对象的内部。对基类的子对象初始化时至关重要的,而且也只有一种方法来保证这一点,那就是在派生类的构造器中调用基类的构造器,而基类的构造器具有执行基类初始化所需的所有能力和知识。
      在无参构造器时, java会自动在派生类的构造器中插入对基类的构造器的调用。
   
Java代码  收藏代码
public class Humans {    
    Humans(){ 
        System.out.println("我是人!"); 
    } 
     

  
Java代码  收藏代码
public class Student extends Humans{ 
 
    Student(){ 
        System.out.println("我是学生!"); 
    } 
 


Java代码  收藏代码
public class test { 
    public static void main(String args[]){ 
          new Student(); 
    } 

输出结果为:
      我是人!
     我是学生!
可以发现,总是基类的构造器先被初始化。
但是当构造器有参数时,那就必须使用关键字super现实地编写调用基类构造器的代码,并且匹配适当的参数列表。
Java代码  收藏代码
public class Humans { 
     
    private String name; 
 
    Humans(String name){ 
        System.out.println("我是叫"+name+"的人"); 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 


Java代码  收藏代码
public class Student extends Humans{ 
     
    private String name; 
 
    Student(String name){ 
        super(name); 
        System.out.println("我是学生!"); 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 


Java代码  收藏代码
public class test { 
    public static void main(String args[]){ 
        new Student("zhangsan"); 
    } 

输出结果:
我是叫zhangsan的人
我是学生!
如果注释掉上面的super(name);将会报错。原因是派生类必须调用基类构造器。因为实例化派生类时,基类也会被实例化,如果不调用基类的构造器,基类将不会被实例化,所以派生类没有调用基类构造器会报错。

但是如果Humans的代码变成这样就不会错。如下代码:
Java代码  收藏代码
public class Humans { 
     
    private String name; 
 
    Humans(){ 
        System.out.println("我是人!"); 
    } 
    Humans(String name){ 
        System.out.println("我是叫"+name+"的人"); 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 


Java代码  收藏代码
public class Student extends Humans{ 
     
    private String name; 
     
    Student(String name){ 
        //super(name); 
        System.out.println("我是学生!"); 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 


Java代码  收藏代码
public class test { 
    public static void main(String args[]){ 
        new Student("zhangsan"); 
    } 

输出结果为:
        我是人!
        我是学生!
原因是,如果基类有一个无参的构造器,就算派生类不用super显示调用基类的构造函数,编译器也会自动
去调用基类的无参构造函数。
所以上面的代码不会报错,输出结果也不是
        我是叫zhangsan的人
        我是学生!
而是
        我是人!
        我是学生!
派生类继承了基类的所有public和protected属性和方法,代码如下:
Java代码  收藏代码
public class Humans { 
     
    public String sex; 
     
    protected int age ; 
     
    private String name; 
 
 
    Humans(String sex,String name,int age){ 
        this.sex = sex; 
        this.name = name; 
        this.age = age; 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 


Java代码  收藏代码
public class Student extends Humans{ 
     
    Student(String sex ,String name,int age){ 
        super(sex,name,age); 
    } 


Java代码  收藏代码
public class test { 
    public static void main(String args[]){ 
        Student s = new Student("男","zhangsan",10); 
        System.out.println(s.sex); 
        System.out.println(s.name); 
        System.out.println(s.age); 
    } 

上面的System.out.println(s.name);会报错,因为name是private属性,如需访问,采用get方法:

Java代码  收藏代码
System.out.println(s.getName()); 
输出结果为:

zhangsan
10

如果派生类定义了和基类一样的属性或方法,将覆盖基类的属性和方法。如将student改为如下代码:
Java代码  收藏代码
public class Student extends Humans{ 
     
    public String sex; 
     
    protected int age ; 
     
    private String name; 
     
    Student(String sex ,String name,int age){ 
        super(sex,name,age); 
    } 
     
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 

输出结果为:
null
null
0
因为只有基类的属性在构造时赋值了,派生类的没有,当访问这些属性时,访问的是派生类的属性,所以全为null或者0。
只有当派生类的属性也被实例化时,才会得到属性的值。代码改为如下:
Java代码  收藏代码
public class Student extends Humans{ 
     
    public String sex; 
     
    protected int age ; 
     
    private String name; 
     
    Student(String sex ,String name,int age){ 
        super(sex,name,age); 
        this.sex = sex; 
        this.name = name; 
        this.age = age; 
    } 
     
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 


输出结果为:

zhangsan
10

要注意的是,super必须在构造器的最前面,不然会报错。
发表评论
用户名: 匿名