Java三大性质之继承!!!!!

 一.什么是继承

首先,继承是java面向对象语言中的一个重要特性,,它允许一个类继承另一个类的成员变量,成员方法,并在这个基础上进行改变 例如动物是哺乳动物的父类,哺乳动物在大部分特性上与动物相同,但是有个别性质上发生了改变,并且可能多出某些性质,这就是继承
class Animal{
    public String name;
    public int age;
    public String color;
    public Animal(String name) {//自己写父类的带参构造函数的时候,则需要让子类中也进行构造,否则编译错误;
        this.name = name;
        System.out.println("Animal(String)");
    }
    public Animal(){
        System.out.println("默认初始化父类");
    }
    public void eat() {
        System.out.println(name+" 正在吃饭!---Animal");
    }
}

这是一个父类对象(动物),它里面存在着它的相关成员变量和成员方法。

 在java中想要使用继承需要关键词extends

访问限定符 class 子类名 extends 父类名 

class Dog extends Animal{
    public Dog(String name) {
        super(name);//调用父类的构造函数,super是关键词可以调用父类构造函数,且必须在第一行super(参数)
        //super不可与this();一起出现,因为都要在第一行;
        System.out.println("DOG的构造方法!");
    }
    //就算自己不去构造构造函数,系统也会自动为父类和子类构造构造函数
    public Dog(){
        super();//可以不写这个,因为编译器会自动为你写一个;(在父类中同理)
        System.out.println("默认初始化子类");
    }
    public void wangWang() {
        System.out.println(name+" 正在旺旺旺!!");
    }
    public void eat() {
        System.out.println(name+" 正在吃狗粮!");
    }
}

这样,我们就完成了一个初步的继承了,Dog这个类就继承了父类animal的全部成员,包括private成员变量,并且在此之上还进行了某些修改和增加

 在Java中,当涉及到面向对象编程中的继承机制时,子类确实会继承父类的所有成员,包括私有(private)成员。不过需要注意的是,虽然子类继承了这些私有成员,但是由于访问控制的原因,子类并不能直接访问或修改这些私有成员。

 二,为什么要继承

 在Java中,继承和现实中的继承有些类似,但又大相径庭,在Java中的继承本质上是对共性的抽取,从而实现代码的复用,达到简化代码的作用,提高代码的可读性以及代码 的编写效率。

 三,如何使用继承

 

public class demo1 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Dog dog2=new Dog("唐鱼");
        dog2.eat();
        dog2.wangWang();
    }
}

 1、子类会将父类中的成员变量或者成员方法继承到子类中
2、子类继承父类之后,必须要添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了。 

 

 

 如果在子类与父类中出现同名的成员,编译器会优先访问子类本身的成员,和局部变量一样,优先访问内部的,如果需要在子类中访问父类的同名成员,那么需要使用super关键字。该关键字能够特指访问父类的成员,父类的成员变量,成员方法均可通过super关键字特指访问,但是切记,super只能在子类中使用。

 父类

class Animal{
    public String name="小花";

    public int age=10;
    public String color="blue";
}

子类

class Dog extends Animal{
   int  age=15;
   public String name="小王";
   public void test(){
        System.out.println(this.age);
        System.out.println(this.name);
        System.out.println(super.age);
        System.out.println(super.name);
    }

 

 在子类方法中 或者 通过子类对象访问父类成员时:
1、如果访问的成员变量中子类有,则编译器中优先访问子类的成员变量
2、如果访问的成员变量中子类没有,则编译器访问父类继承下来的,如果父类也没有,则编译报错
3、如果访问的成员变量与父类中的成员变量同名,则优先访问子类自己的
4、通过子类对象访问与父类同名方法时,如果父类和子类同名方法的参数列表不同(构成重载),根据调用的方法传递的参数选择合适的方法进行访问,如果没有则编译报错;如果参数列表相同(构成重载),那么需要使用super关键字才可以特指访问父类的方法,否则默认访问子类的方法

 四,super关键字的介绍

  当场景需要或者程序员设计问题,子类和父类中有可能会出现名称相同的成员,如果想要在子类中访问父类的同名成员,那么就需要使用到super关键字,该关键字的主要作用是:在子类中特指访问父类成员.

 关键字访问父类的成员时需要使用super关键字,super关键字是获取子类对象中从父类继承下来的部分
    如果子类和父类的方法构成重载,可以直接通过参数列表区分访问父类还是子类的方法
    如果子类和父类 的方法构成重写,此时需要调用父类的方法则需要使用super

 

class Base{
    public int a;
    public int b;
    public int c;
    public void func1(){
        System.out.println("父类func1()");
    }
}
 public void func1(int a) {
        System.out.println("func1(int)");
    }
    public void func1() {
        System.out.println("子类func1()");
    }
    public  void testFunc() {
        func2();
        func1(10);//子类的   重载!!
        func1();//子类的
        super.func1();//可以在子类中通过super来调用父类中的成员
    }

 注意:super调用父类只能在非静态成员方法中调用,因为super依赖于对象,在子类方法中通过super才能调用父类成员。

 那么有人就要问了,主播主播,在子类中有没有明确方法可以调用自身的成员呢?

这当然是有的,有的!这个就是this,这个在之前类和对象也有过学习

 通过this.()调用自身方法,通过类似this.a调用自身成员变量,这个和默认是一样的

 

public  void testFunc() {
        func2();
        func1(10);//子类的   重载!!
       this.func1();//子类的
        super.func1();//可以在子类中通过super来调用父类中的成员
    }
 五,子类和父类的构造函数

 相信大家总是被子类和父类的构造函数的编译错误所困扰过,这次我一次讲清

 首先,我们可以将构造方法大体分为2中:显示构造和默认构造

其次,我们可以继续细分显示构造为无参和含参

 当父类中显示定义的是无参构造方法或者父类没有定义构造方法时,子类中显示定义了含参构造方法,或者是没有显示定义构造方法,或者是显示定义无参的构造方法,编译器会自动调用父类的构造方法,不需要我们手动调用

public Animal(){
        System.out.println("默认初始化父类");
    }
 public Dog(){
        super();//可以不写这个,因为编译器会自动为你写一个;(在父类中同理)
        System.out.println("默认初始化子类");
    }

这也就意味着:子类中的构造方法都会默认调用父类的构造方法,并且是先执行父类的构造方法才执行子类的构造方法 。先有父后有子

 当父类显示定义含参的构造方法时,编译器就不会在子类的构造方法中自动调用父类的构造方法,此时就需要我们手动调用了。否则就会出现编译报错

  public Animal(String name) {//自己写父类的带参构造函数的时候,则需要让子类中也进行构造,否则编译错误;
        this.name = name;
        System.out.println("Animal(String)");
    }
public Dog(String name) {
        super(name);//调用父类的构造函数,super是关键词可以调用父类构造函数,且必须在第一行super(参数)
        //super不可与this();一起出现,因为都要在第一行;
        System.out.println("DOG的构造方法!");
    }

由四,五总的来说:

super关键字有三个用处:
1、通过super关键字调用父类的成员变量
2、通过super关键字调用父类的成员方法
3、通过super( )调用父类的构造方法

使用super()时候需要注意的几点:
1、super()的参数列表需要和父类构造方法的参数列表一致
2、super()必须要在构造方法中的第一条语句
3、子类的构造方法的参数列表需要含有父类构造方法的参数
4、super()只能在子类构造方法中出现一次,并且不能和this()同时出现
5、若父类显示定义无参或者默认的构造方法时,在子类构造方法第一行默认有隐含的super()调用,即调用父类的构造方法
6、如果父类构造方法是带有参数的,此时需要程序员为子类显示定义构造方法,并在子类构造方法中选择适合的父类构造方法调用,否则编译失败。

7.由此可以得出为什么super关键字依赖于子类,因为在子类对象被构造的时候才调用父类的构造函数,所以说super依赖于子类对象

 六,继承中的初始化

 常用的代码块的作用基本上是对对应的变量进行初始化,而不同给代码块之间的执行顺序是不一样的。在没有继承的基础上代码块之间的执行顺序是:静态代码块,构造代码块,构造方法,那么我们就有疑问,我们在继承中的顺序是什么呢?

 通过一系列代码的实现我们可以得出,它的顺序是

1.父类的静态代码块

2.子类的静态代码块

3.父类的构造代码块

4.父类的构造方法

5.子类的构造代码块

6。子类的构造方法

 

 父子类的出现也使得访问权限被细分为更多种

 七,多继承

 java中支持多继承和单继承,但是不支持菱形继承(c++中支持)

 如果不想被继承,可以使用final修饰类,表示当前类不支持被继承

  final的作用:
1、修饰变量,表示常量,不可更改
2、修饰类,表示当前类不可被继承
3、修饰方法,表示当前方法不支持被重写

 

 八,组合

  组合不是一种思想,而是一种编写代码的手段,组合是一种表达类之间关系的方式,也能够达到重用代码的效果
    仅仅是将一个类的实例作为另外一个类的成员变量

class Student {
    int a=3;
}

class Teacher {

}
//组合 其实就是代码的 实现方式
class School {
    public Student student;
    public Teacher teacher;

}

public class Test3 {
    public static void main(String[] args) {

        School sc=new School();
        sc.student=new Student();
        System.out.println(sc.student.a);
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值