Java---继承详解
目录
1:继承的介绍
2:继承的特点
(1)特点介绍
(2)实例演示
3:子类可以继承了父类什么
(1)构造方法
(2)成员变量
(3)成员方法
4:成员变量和成员方法的继承特点
(1)成员变量的继承特点
(2)成员方法的继承特点
5:构造方法的访问特点
本篇文章参考了b站的黑马程序员老师的视频
1:继承的介绍
什么是继承呢?嗯...继承是Java面向对象三大特征之一,我们在写类的时候,有时候会发现你新写的类的方法或者属性在你之前写过的类中是有的,那我们在写的话,就显得有点重复了,当然了你写的话是没有错误的,不过在开发中,就显得有点麻烦了。那关于继承中的父类和子类,应该由字面意思好理解的吧。子类继承父类中的属性和方法,子类也可以自己加一些属性和方法。看得出来,继承的好处就是大大地提高了代码的复用性。
class 子类 extends 父类{
//代码
}
子类继承父类
2:继承的特点
(1)特点介绍
在java中只支持单继承,不支持多继承。这跟现实生活中一样啊,一个儿子只有一个爸爸,所以,一个子类只能继承一个父类(但是支持多层继承,就是a继承b,b继承c这样子的)。
(2)实例演示
说的这么多,不如来次实操,来看看下面的需求,我们试着写写。
大猫:吃饭,喝水,抓老鼠
小猫:吃饭,喝水,抓老鼠
大狗:吃饭,喝水,看家,拆家
小狗:吃饭,喝水,看家,跳舞
看上面的话,我们找出重复的方法,来写
这四个我们搞一个类叫animal吧,他们共有的是:吃饭,喝水
大猫小猫又是一个类叫cat吧,有的是抓老鼠
大狗小狗是一个类叫dog吧,他有的是看家
然后大狗小狗类我们分别写个拆家跳舞的方法。
这里我为了方便吧这么多类都写到一起了,你可别学我啊
//测试类
public class test {
public static void main(String[] args) {
smalldog s=new smalldog();
s.dance();
s.drink();
s.eat();
System.out.println("-------");
bigdog t=new bigdog();
t.chaijia();
t.drink();
t.eat();
t.jia();
}
}
public class smalldog extends dog{
public void dance() {
System.out.println("跳舞");
}
}
public class dog extends animal{
public void jia() {
System.out.println("看家");
}
}
public class cat extends animal{
public void mouse() {
System.out.println("抓老鼠");
}
}
public class bigdog extends dog{
public void chaijia() {
System.out.println("拆家");
}
}
public class animal {
public void eat() {
System.out.println("吃饭");
}
public void drink() {
System.out.println("喝水");
}
}
3:子类可以继承了父类什么
(1)构造方法
构造方法子类是无法继承父类的哦!很简单的,写空参和有参的构造方法时,父类和子类的类名你觉得会一致吗?很明显不会的吧,那么就无法继承了。
(2)成员变量
成员变量子类是可以继承父类的,public修饰可以继承,private修饰也可以继承,不过毕竟是私有的,调用的话,我们是要使用set和get方法的,我们可以理解成public直接继承,private上锁,我们再继承的。
public class animal {
private String name;
private int age;
public void setage(int age) {
this.age=age;
}
public void setname(String name) {
this.name=name;
}
public String getname() {
return name;
}
public int age() {
return age;
}
}
public class cat extends animal{
String game;
}
因为这个父类中的 属性是私有的,无法直接操作,想要操作,只能通过set和get方法了
(3)成员方法
成员方法也可以被继承。只不过必须是父类中的虚方法才能被子类继承。那么什么是虚方法呢?虚方法就是方法没有被private,static,final修饰的就是虚方法。我们可以举例看看
public class fu {
public void fushow1() {
System.out.println("父类public");
}
private void fushow2() {
System.out.println("父类private");
}
}
public class zi extends fu{
public void zishow() {
System.out.println("子类方法");
}
}
public class test {
public static void main(String[] args) {
zi s=new zi();
s.zishow();
s.fushow1();
s.fushow2();
}
}
但是测试类的代码却报错了!原因就是private修饰了。
4:成员变量和成员方法的继承特点
(1)成员变量的继承特点
成员变量的继承特点就是就近原则,谁离我近,我就用谁。具体我们看看例子吧
public class fu {
String name="fu";
}
public class zi extends fu{
String name="zi";
public void show() {
String name="zishow";
System.out.println(name);
}
}
public class test{
public static void main(String[] args) {
zi s=new zi();
s.show();
}
}
这时候输出的是zishow(就近原则)
public class fu {
String name="fu";
}
public class zi extends fu{
String name="zi";
public void show() {
System.out.println(name);
}
}
public class test{
public static void main(String[] args) {
zi s=new zi();
s.show();
}
}
这时候输出的是 zi
public class fu {
String name="fu";
}
public class zi extends fu{
public void show() {
String name="zishow";
System.out.println(name);
}
}
public class test{
public static void main(String[] args) {
zi s=new zi();
s.show();
}
}
这时候输出的是 fu
那如果我想控制我的输出,想让他是父类中的就是父类中的,想是子类中的成员变量,想是局部变量该如何做呢?使用super和this关键字就行,看例子我们就懂了,上代码!
public class fu {
String name="fu";
}
public class zi extends fu{
String name="zi";
public void show() {
String name="zishow";
System.out.println("局部变量"+name);
System.out.println("成员变量"+this.name);
System.out.println("父类"+super.name);
}
}
public class test{
public static void main(String[] args) {
zi s=new zi();
s.show();
}
}
(2)成员方法的继承特点
成员方法的继承特点其实也没什么好说的,不过其中子类与父类中的方法名如果重复了,子类是可以重写的,所以也就有了方法重写这个词汇了。也就是重写的这个方法是子类覆盖的父类的,也可以理解成补充吧。重写也是有限制的,并不是父类中的什么方法都可以重写的。
1:重写的方法的名称和形参都必须与父类保持一致
2:子类重写方法时,子类的访问权限必须大于等于父类的(空着不写<protected<public)
3:子类的返回值类型必须小于等于父类
4:只有被添加到虚方法表中的方法才可以被重写
5:实在不理解,建议子类尽量和父类保持一致
@Override是对于重写的注解,一般先写她,后面是重写方法
说的这么多,来举个例子吧。
public class fu {
public void show() {
System.out.println("父类的展示");
}
public void eat() {
System.out.println("父类的吃饭");
}
public void drink() {
System.out.println("父类的喝水");
}
}
public class zi extends fu{
@Override
public void show() {
System.out.println("重写变成子类的展示");
}
@Override
public void drink() {
System.out.println("重写变成子类的喝水");
}
}
public class test{
public static void main(String[] args) {
zi s=new zi();
s.drink();
s.show();
s.eat();
}
}
5:构造方法的访问特点
第三大点说了构造方法是无法继承的,那它有什么访问特点啊?注意哦,是访问特点,千万别看成了继承特点哦
1:父类中的构造方法是不会被子类继承的
2:子类中的所有构造方法默认先访问父类中的无参构造,再执行自己
理由是什么?
1:子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类中的数据
2:子类在初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
怎么调用父类构造方法呢?
1:子类构造方法的第一行语句默认是:super(),不写也存在,且必须在第一行
来,我们看个代码实例加强点印象吧!
public class fu {
String name;
int age;
public fu() {
System.out.println("父类中的无参构造");
}
public fu(String name,int age) {
this.name=name;
this.age=age;
}
}
public class zi extends fu{
public zi() {
super();
System.out.println("子类的无参构造");
}
public zi(String name,int age) {
super(name,age);
}
}
public class test{
public static void main(String[] args) {
zi s=new zi("jk",20);
zi a=new zi();
System.out.println(s.name+" "+s.age);
}
}