(1)继承
是面向对象程序设计的又一重要特性,是面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承是一种由已有类创建新类的机制。被继承的类称为基类或父类,由继承形成的类称为派生类或者子类。
继承的特点:
1.Java的继承具有单继承的特点,一个父类可以同时拥有多个子类,每个子类只能有一个父类。
2.子类还可以有它的子类,但在下一层关系中成为了父类。
3.类的关键是通过关键字extends来实现的其格式为
[访问权限]class 子类名 extends 父类名
public class sheep extends animal{ ... }
4.如果没有extends子句,则这个类直接继承Object。
注意:父类名所指定的类必须是在当前编译单元中可以访问的类,否则会产生错误。
(2)继承成员变量和方法:
1.子类和父类在同一个包中,那么子类可以继承父类中的public、protected、和default类型的成员变量和方法。
2.子类和父类不在同一个包中,那么子类可以继承父类的public、protected的成员方法和变量。
3.子类不能继承父类的构造方法。
(2)子类的构造方法
1.子类不能继承父类的构造方法,当用子类的构造方法创建一个子类对象时,子类的构造方法总是先调用父类的某个构造方法。
2.在重载中一个构造方法调用另一个构造方法使用this关键字调用,在子类中调用父类的构造方法,使用super调用。
注意:1.若父类中没有定义构造方法,系统自动为父类添加一个无参的方法体为空的构造方法。
2.若父类定义了无参构造方法,则系统创建对象时自动调用父类添加的无参构造方法。
3.若父类定义中的构造方法都有参数,那么子类方法中的第一语句必须使用super语句调用父类有参的结构方法。
创建一个父类:
public class animal { private String name; private String color; private String sex; public animal(String name, String color, String sex) { this.color=color; this.name=name; this.sex=sex; } public void prtntMsg() { System.out.println("姓名:"+name+",性别:"+sex+",颜色:"+color); } }
子类调用:
public class sheep extends animal{ private String birth; public sheep(String name,String color,String sex,String birth) { super(name,color,sex); this.birth=birth; }
4.super和this调用非常相识,不同之处在于super调用的是父类的构造方法,this调用的是同一类中重载的构造方法。所以super和this不会出现在同一个方法体中。
(3)覆盖
1.什么是覆盖?
父类中的变量被隐藏和重写的情况。
2.两大覆盖类型:
成员变量的覆盖:子类中定义的成员变量和父类中的成员变量同名,不管其类型是否相同,父类中的同名成员变量都要被隐藏,子类就无法继承父类的该变量。
成员方法的覆盖:子类中定义的成员方法和父类中的成员方法在方法名、返回类型、参数个数及类型方面都相同。
-
如何解决覆盖?
子类如果想使用父类中的被隐藏的成员方法和成员变量,必须使用关键字super,格式为:
super.数据成员 super.成员方法(参数)
举例:在父类animal中添加了输出各个属性值的toString()的方法,并输出姓名。
public class animal { private String name; private String color; private String sex; public animal(String name, String color, String sex) { this.color=color; this.name=name; this.sex=sex; } public void prtntMsg() { System.out.println("姓名:"+name+",性别:"+sex+",颜色:"+color); } public String toString() { return "animal类属性:name="+name; } }
在子类中(sheep类)中对该方法进行重写。
public class sheep extends animal{ private String birth; public sheep(String name,String color,String sex,String birth) { super(name,color,sex); this.birth=birth; } public String getbirth() { return birth; } public void setbirth(String name) { this.birth=birth; } public String toString() { return"sheep类属性:birth"+birth+"继承自父类"+super.toString(); } }
在子类中最后没有输出继承父类的toString()的属性值,说明父类中的属性值方法被覆盖。
super的使用有两种情况:
1.访问被子类隐藏的超类的成员变量和成员方法,格式为:
super.数据成员 super.成员方法(参数)
2.虽然构造方法不能够继承,但利用super关键字,子类构造方法中也可以调用父类的构造方法。调用的格式为:
super(<参数列表>)
(4)final关键字
final关键字可用于修饰类、变量和方法。
用final修饰类时,表示此类是最终类,不能派生子类。
用final修饰变量,表示该变量一旦获得了初始值,程序中的其他部分可以访问,但不能够修改。
用final修饰成员方法,则该方法不能再被子类所重新写,即该方法为最终方法。
举例如下:
public class Final { public static void main(String []args) { final String s="java";//定义final局部变量时指定其默认值,不能再对其重新赋值 s="esplice";//报错的原因是因为不能对其重新赋值,此语句不合法。 final int a;//a被定义为final局部变量时没有指定其默认值,对其可被赋值一次 a=5;//此次合法 a=6;//此次不合法 } }
巩固习题:
定义教师工作证类TeactherCard,包括编号、姓名、性别、出生年月、职务和签发时间;
定义学生证类StudentCard,包括编号、姓名、性别、出生年月、系别和入学时间。
1.创建一个父类Card,并输出教师和学生证的信息。
public class Card { String ID; String name; String sex; String birth; public Card(String ID,String name,String sex,String birth) { this.birth=birth; this.ID=ID; this.name=name; this.sex=sex; } public void printFor() { System.out.println("姓名:"+name+",编号为:"+ID+"性别:"+sex+"出生年月:"+birth); } }
2.创建TeacherCard类。
public class TeacherCard extends Card { String position;//position职务 String date;//date时间 public TeacherCard(String ID, String name, String sex, String birth) { super(ID, name, sex, birth); this.position=position; this.date=date; } public void printFor() { super.printFor(); System.out.println("职务:"+this.position); System.out.println("入职时间:"+this.date); } }
3.创建StudentCard类。
public class StudentCard extends Card{ String position; String date; public StudentCard(String ID, String name, String sex, String birth) { super(ID, name, sex, birth); this.position=position; this.date=date; } public void printFor() { super.printFor(); System.out.println("系别:"+this.position); System.out.println("入学时间:"+this.date); } }
4.创建多个测试类对两个子类进行测试。