面向对象特征之二:继承性(inheritance)
我们都知道类是java中最重要的东西,“万事万物皆对象”一直是java的口号,对对象的功能进行扩展是十分重要的,这就引入了我们今天讲的 继承性!
(废话扯一波)我们知道定一个person类,包括了string name,int age 等,有了这个类以后,我们如果想定义一个student类,如果没有现在的知识点,我们是不是又得重新去定义一个学生类中的name age呢?这是不是十分冗余呢?所以继承性诞生了,少说废话,进正题吧!
为什么要有继承?
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行为,只要继承那个类即可。
此处的多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。可以理解为:“子类 is a 父类”
类继承语法规则 :
class Subclass extends SuperClass{ }
作用:
继承的出现减少了代码冗余,提高了代码的复用性。
继承的出现,更有利于功能的扩展。
继承的出现让类与类之间产生了关系,提供了多态的前提。
注意:
不要仅为了获取其他类中某个功能而去继承
子类继承了父类,就继承了父类的方法和属性。
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和 方法。
在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,
而是对父类的“扩展”。
讲到这里,你也差不多明白了子父类的关系了。那我们顺便说一下一个特别重要的东西
方法的重写(override/overwrite)
定义 :
在子类中可以根据需要对从父类中继承来的方法进行改造,也称 为方法的 重置、覆盖 。在程序执行时,子类的方法将覆盖父类的方法。
要求 :
1. 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
2. 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
3. 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
子类不能重写父类中声明为private权限的方法
4. 子类方法抛出的异常不能大于父类被重写方法的异常
注意:
子类与父类中同名同参数的方法必须同时 声明为非static的(即为重写),或者同时声明为
static的(不是重写) 。因为 static 方法是属于类的,子类无法覆盖父类的方法
那我们想要掉用父类中的方法呢?这就要提到我们的关键字super了
在Java类中使用super来调用父类中的指定操作:
super可用于访问父类中定义的属性
super可用于调用父类中定义的成员方法
super可用于在子类构造器中调用父类的构造器
注意:
尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
super的追溯不仅限于直接父类
super和this的用法相像,this代表本类对象的引用,super代表父类的内存
空间的标识
class Person { String name = "张三"; protected int age; public String getInfo() { return "Name: " + name + "\nage: " + age; } } class Student extends Person { protected String name = "李四"; private String school = "New Oriental"; public String getSchool() { return school; } public String getInfo() { return super.getInfo() + "\nschool: " + school; } } public class text { public static void main(String[] args) { Student st = new Student(); System.out.println(st.getInfo()); }}
Name: 张三
age: 0
school: New Oriental
调用父类的构造器
子类中所有的构造器默认都会访问父类中空参数的构造器
当父类中没有空参数的构造器时,子类的构造器必须通过this(参 数列表)或者super(参数列表)语句指定调用本类或者父类中相应的 构造器。同时,只能”二选一”,且必须放在构造器的首行
如果子类构造器中既未显式调用父类或本类的构造器,且父类中又 没有无参的构造器,则编译出错
public class Person { private String name; private int age; private Date birthDate; public Person(String name, int age, Date d) { this.name = name; this.age = age; this.birthDate = d; } public Person(String name, int age) { this(name, age, null); } public Person(String name, Date d) { this(name, 30, d); } public Person(String name) { this(name, 30); } } class Student extends Person { private String school; public Student(String name, int age, String s) { super(name, age); school = s; } public Student(String name, String s) { super(name); school = s; } // 编译出错: no super(),系统将调用父类无参数的构造器。 public Student(String s) { school = s; } }
class person{ int age; public preson(int age) { this.age=age; } } class student extends person { String name; public student(String nameString)//报错!!! { this.name=nameString; } }