java----面向对象之继承

问题:

为什么要有继承

  • 继承的含义
  • 继承的好处

答:

1.继承的含义

继承:在java中指的是“一个类”可以“继承自”“另一个类”。 "被继承的类"叫做: 父类/超类/基类,"继承其他类的类"叫做:子类。继承后,“子类”中就“拥有”了“父类”中所有的成员(成员变量、成员方法)。 “子类就不需要再定义了”。

2.继承的好处
  1. 提高代码的复用性(减少代码冗余,相同代码重复利用)。
  2. 使类与类之间产生了关系。

  • 继承:在java中指的是“一个类”可以“继承自”“另一个类”。 "被继承的类"叫做: 父类/超类/基类,"继承其他类的类"叫做:子类。继承后,“子类”中就“拥有”了“父类”中所有的成员(成员变量、成员方法)。 “子类就不需要再定义了”。

继承的格式

通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

class 父类 {
	...
}

class 子类 extends 父类 {
	...
}

需要注意:Java是单继承的,一个类只能继承一个直接父类,并且满足is-a的关系,例如:Dog is a Animal, Student is a Person

继承的演示
人类:
public class Person {
    // 成员变量
    String name;
    int age;
    
    // 功能方法
    public void eat(){
        System.out.println("吃东西...");
    }

    public void sleep(){
        System.out.println("睡觉...");
    }
}
老师类: extends 人类
public class Teacher extends Person {
	double salary;// 独有的属性
    public void teach(){}// 独有的方法
}
学生类: extends 人类
public class Student extends Person{

}
测试:
public class Test {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        System.out.println(t.name);
        System.out.println(t.age);
        t.eat();
        t.sleep();
    }
}
  • 通过继承可以将一些共性的属性,行为抽取到一个父类中,子类只需要继承即可,提供了代码的复用性

  • 继承后构造方法的访问规则
  • 继承后私有成员的访问规则

  • 继承后非私有成员的访问规则**

继承后构造方法的访问规则
  • 构造方法不能被继承

    public class Fu{
        public Fu(){
        }
        public Fu(String name,int age){
        }
    }
    public class Zi extends Fu{
    }
    public class Demo {
        public static void main(String[] args) {
            Zi z = new Zi("刘德华", 17);//编译错误,Zi类没有全参构造
        }
    }
    
    
继承后私有成员的访问规则
  • 父类的“私有成员”可以被子类继承,但子类不能被直接访问。

    public class Fu{
        private int num = 100;//私有成员,只能在父类内部使用。
        private void method(){
            System.out.println("私有成员方法");
        }
    }
    public class Zi extends Fu{
    
    }
    public class Demo {
        public static void main(String[] args) {
            Zi z = new Zi();
    	    System.out.println(z.num);// 编译错误
            z.method();// 编译错误
        }
    }
    
    
继承后非私有成员的访问规则
  • 当通过“子类”访问非私有成员时,先在子类中找,如果找到就使用子类的,找不到就继续去“父类”中找。

    public class Fu{
        int money = 100;
        public void method(){
            System.out.println("Fu 类中的成员方法method");
        }
    }
    public class Zi extends Fu{
        int money = 1;
         public void method(){
            System.out.println("Zi 类中的成员方法method");
        }
    }
    public class Demo{
        public static void main(String[] args){
            Zi z = new Zi();
            System.out.println(z.money);//1
            z.method();// Zi 类中的成员方法method
        }
    }
    

方法重写

方法重写的概念

方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现

public class Fu{
    public void eat(){
        System.out.println("我吃牛肉炖土豆...");
    }
}
public class Zi extends Fu{
	@Override
    public void eat(){//方法重写
        System.out.println("我吃红烧狮子头...");
    }
}
//测试类
public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.eat();// 我吃红烧狮子头...
    }
}

重写的注意事项
  • 方法重写是发生在子父类之间的关系。

  • 子类方法重写父类方法,返回值类型、方法名和参数列表都要一模一样。

  • 子类方法重写父类方法,必须要保证权限大于等于父类权限。

    • 访问权限从大到小: public protected (默认) private
  • 使用@Override注解,检验是否重写成功,重写注解校验!

    • 建议重写方法都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!

this和super关键字

  • this:存储的“当前对象”的引用;
    • this可以访问:本类的成员属性、成员方法、构造方法;
  • super:存储的“父类对象”的引用;
    • super可以访问:父类的成员属性、成员方法、构造方法;
this关键字的三种用法
  • this访问本类成员变量: this.成员变量

    public class Student{
        String name = "张三";
        public void show(){
            String name = "李四";
            System.out.println("name = " + name);// 李四
            System.out.println("name = " + this.name);// 张三
        }
    }
    
  • this访问本类成员方法: this.成员方法名();

    public class Student{
        public void show(){
            System.out.println("show方法...");
            this.eat();
        }
        public void eat(){
            System.out.println("eat方法...");
        }
    }
    
  • this访问本类构造方法: this()可以在本类的一个构造方法中,调用另一个构造方法

    public class Student{
        public Student(){
            System.out.println("空参构造方法...");
        }
    
        public Student(String name) {
            this();//当使用this()调用另一个构造方法时,此代码必须是此构造方法的第一句有效代码。
            System.out.println("有参构造方法...");
        }
    }
    public class Demo {
        public static void main(String[] args) {
            Student stu2 = new Student();
        }
    }
    
super关键字的三种用法
  • super访问父类的成员变量: super.父类成员变量名

    class Fu{
        int num = 100;
    }
    
    class Zi extends Fu{
        int num = 10;
    
        public void show(){
            int num = 1;
            System.out.println("局部变量num:"+num);// 1
            System.out.println("Zi 类中的num:"+this.num);// 10
            System.out.println("Fu 类中的num:"+super.num);// 100
    
          }
    }
    
  • super访问父类的成员方法: super.成员方法名();

    class Fu{
        public void method1(){
            System.out.println("Fu method1...");
        }
    }
    
    class Zi extends Fu{
        public void show(){
            // 访问父类的method1方法
            super.method1();
        }
    
        @Override
        public void method1(){
            super.method1();// 调用父类的method1方法
            System.out.println("Zi method1...");
        }
    }
    
  • super访问父类的构造方法: super()

    public class Fu{
        public Fu(){
            System.out.println("Fu 类的空参构造方法..");
        }
        public Fu(String name, int age) {
            System.out.println("Fu 类的有参构造方法..");
        }
    }
    public class Zi extends Fu{
        public Zi(){
            super();// 调用父类的空参构造方法
            System.out.println("Zi 类的空参构造方法..");
        }
        public Zi(String name,int age){
            super(name,age);// 调用父类的有参构造方法
             System.out.println("Zi 类的有参构造方法..");
        }
    }
    public class Demo {
        public static void main(String[] args) {
            Zi zi = new Zi();
            System.out.println("----------------------");
            Zi z2 = new Zi("刘德华", 17);
        }
    }
    
    

小结

  • this关键字的三种用法:
       this可以访问本类的成员变量: this.成员变量         一般用来区分同名的成员变量和局部变量
       this可以访问本类的成员访问:
       this可以访问本类的构造方法:
            空参构造: this();
            有参构造: this(实参);
                注意:
                     1.只能在本类的构造方法中使用this调用其他构造方法
                     2.在本类的构造方法中使用this调用其他构造方法,必须放在该构造方法的第一行,否则会报错
                     3.两个构造方法不能使用this相互调用
    
  • super关键字的三种用法:
         super可以访问父类的成员变量: super.成员变量         一般用来区分父子类中同名的成员变量
         super可以访问父类的成员方法: super.成员方法(实参);   一般用来在子类中访问父类的成员方法
         super可以访问父类的构造方法:
              空参构造: super();
              有参构造: super(实参);
               注意:
                     1.必须在子类的构造方法中,使用super调用父类的构造方法
                     2.在子类的构造方法中,使用super调用父类的构造方法,必须放在子类构造方法的第一行
    

super的注意事项

  • 关于super的注意事项
super的注意事项一
  • super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推…

    class Ye{
        int num = 10;
        public void method(){
            System.out.println("Ye method");
        }
    }
    class Fu extends Ye{
        int num = 100;
        public void method(){
            System.out.println("Fu method");
        }
    }
    class Zi extends Fu{
        int num = 1000;
        public void show(){
            System.out.println(super.num);
            super.method();
        }
    }
    
    public class Test {
        public static void main(String[] args) {
    
            Zi zi = new Zi();
            zi.show();
        }
    }
    
    
super的注意事项二
          super的注意事项二
            1.子类的构造方法默认会调用父类的空参构造方法
            2.如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错
          问题: super调用父类的构造方法有什么用?
          结果: 为了在创建子类对象的时候,初始化从父类继承过来的属性
class Fu1{
    public Fu1(){
        System.out.println("Fu1 空参构造");
    }

    public Fu1(int num){
        System.out.println("Fu1 有参构造");
    }
}

class Zi1 extends Fu1{
    public Zi1(){
        // super();
    }

    public Zi1(int num){
        // super();
    }
}

// 问题: super调用父类的构造方法有什么用?
class Person{
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void show(){
        System.out.println(name+","+age);
    }
}

class Student extends Person{
    public Student(String name,int age){
       super(name,age);
    }
}

public class Test2 {
    public static void main(String[] args) {
       
        // 通过调用子类的空参构造方法,创建子类对象
        // Zi1 zi = new Zi1();

        // 通过调用子类的有参构造方法,创建子类对象
        //Zi1 zi = new Zi1(100);

        // 创建Student类的对象
        Student stu = new Student("张三", 18);
        stu.show();

    }
}


小结

  • super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推…
  • 子类的构造方法默认会调用父类的空参构造方法,如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错
  • 子类构造方法中使用super调用父类的构造方法,是为了在创建子类对象的时候,初始化从父类继承过来的属性

知识点–2.7 继承体系对象的内存图

  • 继承体系内存图原理—父类空间优先于子类对象产生

    在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。

  • 书写继承案例

    class Fu {
        int num = 10;
        int numFu = 100;
    
        public void method() {
            System.out.println("Fu method方法");
        }
    }
    
    class Zi extends Fu {
        int num = 20;
        int numZi = 200;
    
        @Override
        public void method() {
            System.out.println("Zi method方法");
        }
    
        public void show(){
            int num = 30;
            System.out.println("局部变量的值num:"+num);// 30
            System.out.println("本类的成员变量的值num:"+this.num);// 20
            System.out.println("父类的成员变量的值num:"+super.num);// 10
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Zi zi = new Zi();
            zi.show();// 30 , 20 , 10
            zi.method();// Zi method方法
        }
    }
    
    

继承的特点

  • Java只支持单继承,不支持多继承。
  • 一个类只能有一个父类,但是可以有多个子类。
  • 可以多层继承。

讲解:

  1. Java只支持单继承,不支持多继承。
  // 一个类只能有一个父类,不可以有多个父类。
class A {
    
}
class B {
    
}
class C1 extends A {// ok
    
} 
class C2 extends A, B {// error
    
} 
  1. 一个类只能有一个父类,但可以有多个子类。
  // A可以有多个子类
class A {
    
}
class C1 extends A {
    
}
class C2 extends  A {
    
}
  1. 可以多层继承。
class A /*extends Object*/{// 爷爷   默认继承Object类
    
}
class B extends A {// 父亲
    
}
class C extends B {// 儿子
    
}

补充: 顶层父类是Object类。所有的类默认继承Object,作为父类。

class A {} 默认继承Object类 直接继承Object类

class B extends A{} B的父类就是A,但是A的父类是Object类 间接继承Object类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值