JAVA基础——类的继承
一、概念
继承的概念:类似于他的字面意思,指的是一类事务从另一类事物那里继承了该类事务所具有的一些属性和行为。子类(派生类)可以继承父类(基类)的属性和行为。
继承的三大知识点:
1.继承
关键词:extends
格式:public class 子类(派生类) extends 父类(基类){}
注意:
①继承可以是多层次的,儿子继承父亲,父亲继承爷爷,爷爷继承…
②JAVA只支持单继承,一个父类可以有多个子类,而一个子类只能继承一个父类。
③子类可以继承父类的所有方法和属性,但是私有属性不能直接使用,还是要设置相应的set/get等方法使用。
例如我们写一个学生类Student,
public class Student {
private String name;//姓名属性
//设置、获取姓名
public void setname(String n){
name=n;
}
public String getname() {
return name;
}
//学习状态函数
public void study() {
System.out.println(name+"在学习");
}
}
再写一个大学生类UNstudent继承Student
public class UNstudent extends Student{
}
这时实例化一个子类Unstudent对象,可以看到它调用了父类Student的方法,继承了父类的属性和行为。
public static void main(String[] args) {
UNstudent un=new UNstudent();
un.setname("张三");
un.study();
}
2.重写(覆盖)
在子类中重新定义父类中的方法,重写后调用时调用子类的方法,如果子类中没有就调用父类的方法。
注意:
①重写必须是两个有继承关系的类之间的。
②重写时必须同名同参,即返回值类型,方法名,参数类型(个数、顺序)都一致。
我们在子类UNstudent中重写一下Study方法
public class UNstudent extends Student{
//重写学习状态函数
public void study() {
System.out.println(getname()+"在学习高等数学");
}
}
运行后得到如下结果
可以看到子类重写父类的方法以后,调用的是子类的方法。
值得注意的是,重写时候的格式,以及子类不能直接使用父类的私有属性name,要用我们构造好的getname获取。
3.类型转换
①自动转型(向上转型):
存在继承关系,子类向父类自动转型。也就是说子类可以向上转化为父类类型。
向上转型顾名思义是从下到上的转换方式,当存在继承关系时,用子类对象实例化父类对象时,是父类类型。
格式:
父类 对象变量名=new 子类()
例如我们新建一个Teacher类,在里面写一个teach方法让老师可以看到学生的学习状态,以学生Student对象为参数。
public class Teacher {
//老师看到学生学习状态方法
public void teach(Student s) {
s.study();
}
}
在主函数中实例化一个Teacher对象,看看自动转型结果
public static void main(String[] args) {
/**
* 自动转型
*/
Student un=new UNstudent();
un.setname("张三");
Teacher t=new Teacher();
t.teach(un);
}
得到结果
可以看到,teach方法需要的是Student,即父类对象作为参数,而此时通过子类对象实例化了父类对象un,程序正常运行且调用的是子类方法。子类对象可以向上转为父类对象,调用的方法依然是子类重写的方法。
注意:
此时如果实例化对象时没有用父类对象名引用子类对象,而只是实例化子类对象,即
UNstudent un=new UNstudent();
得到的结果是一样的,因为此时调用teach方法时,子类对象un作为参数传递过去时被Student s自动转型为父类类型
public void teach(Student s)
我们再给子类UNstudent加一个父类Student没有的方法,输出专业名称printproject()。
public class UNstudent extends Student{
//重写学习状态函数
public void study() {
System.out.println(getname()+"在学习高等数学");
}
//输出专业名称
public void printproject() {
System.out.println("计算机专业");
}
用已经自动转型的父类类型对象un调用printproject()方法,发现会报错。这是因为向上转型后,只能调用父类的方法或者子类里重写的方法,而不能调用子类中单独的方法。un可以看作是一个父类引用,虽然指向的是子类对象,但是它向上转型,因此也失去了调用子类中单独方法的权利。
优点:
我们假设Student父类有非常多的子类,不止大学生类,也有小学生类,中学生类,高中生类,他们都重写了父类的学习状态函数,有不一样的学习状态。Teacher类的teach方法传递的参数是对象参数,如果没有向上转型,对象参数类型都是不同的子类类型,在Teacher类里如果想要实现每个Student子类的学习状态方法,就要为每一个子类写上不同的teach方法,即
public class Teacher {
//大学生
public void teachU(UNstudent s) {
s.study();
}
//小学生
public void teachX(Xstudent x) {
x.study();
}
//初中生
public void teachC(Cstudent c) {
c.study();
}
........
}
而有了自动转型,所有的子类类型都可以向上转型为父类类型进行传递,而调用方法的时候调用子类重写的方法(如果重写了的话)。这样大大提高了代码的简洁性和扩展性,多个子类可以用同一个方法而具有不同的功能。
②强制转型(向下转型)
有向上转型就有向下转型,向下转型顾名思义是将父类类型对象转型为子类类型对象,需要强制转型。
并不是所有父类对象都可以向下转型,只有这个对象本身就是子类对象向上转型为父类类型对象时,它才可以被强制转型转回子类类型。也就是说想要向下转型,得先向上转型。
格式:子类 子类对象名=(子类)父类对象名
我们来看这样一段代码
Student un=new Student();
UNstudent um=(UNstudent)un;
um.printproject();
此时程序不会报错,但是编译的时候会报错。这是因为un是一个父类对象的实例,它指向的就是父类对象,没有向上转型,是没有办法强制转型为子类对象的。
先让un向上转型
Student un=new UNstudent();
un.printproject();
我们此时程序会报错,因为un向上转型为父类类型后就没有办法调用子类UNstudent中独有的方法了,此时还是父类类型。而将它强制转型后
Student un=new UNstudent();
UNstudent um=(UNstudent)un;
um.printproject();
得到结果
此时un强制转型为了子类类型,可以调用子类中特有的方法了。
好处:向下转型后又可以调用子类中特有的方法了。
以上就是对于java中继承的讨论。