继承—JavaSE

文章目录

  • 1.基础知识
    • 1.1继承的概念
    • 1.2语法
  • 2子类对从父类继承下来的成员的访问
    • 2.1对成员变量的访问
    • 2.2对成员方法的访问
  • 3.super关键字
    • 3.1访问父类的成员变量(super.变量)
    • 3.2访问父类的成员方法(super.方法)
    • 3.3调用父类的构造方法(super())
  • 4.this和super的区别
    • 4.1相同点
    • 4.2不同点
  • 5.代码块的执行顺序问题
  • 6.访问修饰限定符
    • 6.1同一包中的同一类
    • 6.2同一包中的不同类
    • 6.3不同包中的子类
    • 6.4不同包中的非子类
  • 7.java中支持的继承的方式
  • 8.final关键字
    • 8.1修饰变量或字段
    • 8.2修饰类
    • 8.3修饰方法
  • 9.组合

1.基础知识

1.1继承的概念

在保持原有类特性的基础上进行扩展,增加新功能,从而产生新的类,继承主要解决的问题是对共性的抽取,优点是可以实现代码复用

1.2语法

class A extends B{
}

其中:A是子类,也叫派生类;B是父类,也叫基类、超类

class Animal {
    public String name;
    public int age;
    public void eat(){
        System.out.println(this.name + "正在吃");
    }
}
class Dog extends Animal {
    public void swim(){
        System.out.println(this.name + "正在游泳");
    }
}
class Bird extends Animal {
    public String wing;//翅膀
    public void fly() {
        System.out.println(this.name + "正在飞");
    }
}
public class TextDame1 {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.name = "可可";
        animal.eat();
        Dog dog = new Dog();
        dog.name = "小小";//继承了父类的成员变量
        dog.swim();
        dog.eat();//继承了父类的方法
        Bird bird = new Bird();
        bird.name = "大大";
        bird.fly();
    }
}

子类会将父类中的成员变量或者成员方法继承到子类中;子类继承父类之后,要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承
继承—JavaSE_第1张图片

2子类对从父类继承下来的成员的访问

2.1对成员变量的访问

(1) 子类和父类不存在同名成员变量

class A {
    public int a;
    public int b;
}
class B extends  A {
    public int c;
    public void method(){
        a = 10;//访问从父类继承的
        b = 20;
        c = 30;//访问子类自己的
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
//结果:
//    10
//    20
//    30
}

(2)子类和父类存在同名成员变量时,优先访问子类自己的,自己没有才会访问父类的

class A {
    public int a;
    public int b;
}
class B extends  A {
    public boolean b;
    public int c;
    public void method(){
        a = 10;//访问从父类继承的
        b = false;//同名是优先访问子类自己的
        //b = 10;//会报错,因为是优先访问子类自己的,而子类的b的类型是Boolean,而不是整形
        c = 30;//访问子类自己的
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
//结果:
//    10
//    false
//    30
}

2.2对成员方法的访问

(1)子类和父类不存在同名成员方法

class A {
    public int a;
    public int b;
    public void funcA(){
        System.out.println("父类的funcA()方法");
    }
}
class B extends  A {
    public void funcB(){
        System.out.println("子类的funcB()方法");
    }
    public void method(){
        funcA();//调用父类的成员方法
        funcB();//调用子类自己的成员方法
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
//结果:
//父类的funcA()方法
//子类的funcB()方法
}

(2)子类和父类存在同名成员方法时,优先访问子类的成员方法,子类没有才到父类去找

class A {
    public void func(){
        System.out.println("父类的fun()方法");
    }
}
class B extends  A {
    public void func(){
        System.out.println("子类的func()方法");
    }
    public void method(){
        func();
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
//结果:
//    子类的func()方法
}

3.super关键字

super不能使用在静态方法中,super

3.1访问父类的成员变量(super.变量)

class A {
    public int a;
}
class B extends  A {
    public int a;
    public void method(){
        super.a = 10;//此时的a就是访问的父类的成员便量,但是不加super,默认就是子类自己的a
        a = 20;//等价于this.a = 20
        System.out.println(super.a);//10
        System.out.println(a);//20
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
}

3.2访问父类的成员方法(super.方法)

class A {
    public void func(){
        System.out.println("父类的fun()方法");
    }
}
class B extends  A {
    public void func(){
        System.out.println("子类的func()方法");
    }
    public void method(){
        super.func();//访问父类的func方法
        func();//访问子类的func方法,等价于this.func()
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
//结果:
//    父类的fun()方法
//    子类的func()方法
}

3.3调用父类的构造方法(super())

子类继承了父类以后必须先帮助父类进行构造,帮助父类进行构造就是显示调用父类的构造方法,这里此时构造的意义就是分配内存,初始化从父类继承过拉里的父类成员

class A {
    public int a;
    public int b;
    public A(){
        System.out.println("父类不带参数的构造方法");
    }
}
class B extends  A {
    public int c;
    public B(){
        super();//当父类只有一个不带参数的构造方法的时候,子类默认会有super(),帮助父类进行构造
        System.out.println("子类不带参数的构造方法");
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
    }
//结果:
//    父类不带参数的构造方法
//    子类不带参数的构造方法
}
class A {
    public int a;
    public int b;
    public A(int a, int b) {
        this.a = a;
        this.b = b;
    }
}
class B extends  A {
    public int c;
    //不加这个构造方法会报错,是因为,子类继承了父类以后必须先帮助父类进行构造
    public B(){
        super(30,20);
        System.out.println("B不带参数的构造方法");
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
    }
}

4.this和super的区别

4.1相同点

(1)都是java的关键字
(2)都只能在非静态方法中调用,用来访问非静态成员方法和变量
(3)在构造方法中调用,都必须放在构造方法的第一条,且不能同时存在

4.2不同点

(1)this是当前对象的引用,即当前实例方法的对象的引用;super是子类对象从父类继承过来的成员的引用
(2)在非静态成员方法中,this用来访问本类的方法和属性;super用来访问父类继承下来的方法和属性
(3)this是非静态成员方法的一个隐藏参数;super不是隐藏的参数
(4)成员方法中直接访问本类成员时,编译之后会将this还原,即本类非静态成员都是通过this来访问的;在子类中如果通过super访问父类成员,编译之后在字节码层面super实际是不存在的
(5) 在构造方法中,this(…)用于调用本类构造方法;super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现
(6)构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

class A {
    public int a;
    public int b;
    public A(){
        System.out.println("父类不带参数的构造方法");
    }

    public A(int a, int b) {
        this();//调用本类的不带参数的构造方法,这个不写就没有
        this.a = a;
        this.b = b;
        System.out.println("父类带两个参数的构造方法");
    }
}
class B extends  A {
    public int c;
    public B(){
    	//super();//调用父类的不带参数的构造方法,这个不写编译器会自动加上
        super(23,2);//调用父类的带两个参数的构造方法
        System.out.println("父类不带参数的构造方法");
    }
}
public class TextDame2 {
    public static void main(String[] args) {
        B b = new B();
    }
//结果:
//    父类不带参数的构造方法
//    父类带两个参数的构造方法
//    父类不带参数的构造方法
}

继承—JavaSE_第2张图片

5.代码块的执行顺序问题

(1)父类静态代码块优先于子类静态代码块执行,且是最早执行
(2)父类实例代码块和父类构造方法紧接着执行
(3)子类的实例代码块和子类构造方法紧接着再执行
(4)第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行(静态的只有一份)

class Animal {
    public String name;
    public int age;
    static {
        System.out.println("Animal的静态代码块");
    }
    {
        System.out.println("Animal的实例代码块");
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Animal带有两个参数的构造方法");
    }
}
class Dog extends Animal {
    static {
        System.out.println("Dog的静态代码块");
    }
    {
        System.out.println("Dog的实例代码块");
    }

    public Dog() {
        super("小小", 2);
        System.out.println("Dog不带参数的构造方法");
    }
}
public class TextDame1 {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        System.out.println("============");
        Dog dog2 = new Dog();
    }
//结果:
//    Animal的静态代码块
//    Dog的静态代码块
//    Animal的实例代码块
//    Animal带有两个参数的构造方法
//    Dog的实例代码块
//    Dog不带参数的构造方法
//    ============
//    Animal的实例代码块
//    Animal带有两个参数的构造方法
//    Dog的实例代码块
//    Dog不带参数的构造方法
}

6.访问修饰限定符

继承—JavaSE_第3张图片

6.1同一包中的同一类

package extendsText;
public class TextDame2 {
    public int a = 10;
    protected int b = 20;
    int c = 30;
    private int d = 40;

    public static void main(String[] args) {
        TextDame2 textDame2 = new TextDame2();
        System.out.println("同一包中的同一类:" + textDame2.a);
        System.out.println("同一包中的同一类:" + textDame2.b);
        System.out.println("同一包中的同一类:" + textDame2.c);
        System.out.println("同一包中的同一类:" + textDame2.d);
    }
//结果:
//    同一包中的同一类:10
//    同一包中的同一类:20
//    同一包中的同一类:30
//    同一包中的同一类:40
}

6.2同一包中的不同类

package extendText;

public class TextDame2 {
    public int a = 10;
    protected int b = 20;
    int c = 30;
    private int d = 40;
}
package extendText;

public class TextDame1 {
    public static void main(String[] args) {
        TextDame2 textDame2 = new TextDame2();
        System.out.println("同一包中的不同类:" + textDame2.a);
        System.out.println("同一包中的不同类:" + textDame2.b);
        System.out.println("同一包中的不同类:" + textDame2.c);
//        System.out.println("同一包中的不同类:" + textDame2.d);报错,被private修饰的只能在当前类被访问,不同类中使不能访问的
    }
//结果:
//    同一包中的不同类:10
//    同一包中的不同类:20
//    同一包中的不同类:30
}

6.3不同包中的子类

package extendText;

public class TextDame2 {
    public int a = 10;
    protected int b = 20;
    int c = 30;
    private int d = 40;
}
package childText;

import extendText.TextDame2;

public class TextDame3 extends TextDame2 {
    public void method(){
        super.a = 50;
        super.b = 60;
//        super.c = 70;报错,没有写就就是包访问权限,只能在同一个包中访问
//        super.d = 80;报错,被private修饰的只能在当前类被访问
    }
}

6.4不同包中的非子类

package extendText;

public class TextDame2 {
    public int a = 10;
    protected int b = 20;
    int c = 30;
    private int d = 40;
}
package childText;

import extendText.TextDame2;

public class TextDame4 {
    public static void main(String[] args) {
        TextDame2 textDame2 = new TextDame2();
        System.out.println("不一包中的非子类:" + textDame2.a);
//        System.out.println("不一包中的非子类:" + textDame2.b);报错,protected修饰的再不同包中的非子类是不能被访问到的
//        System.out.println("不一包中的非子类:" + textDame2.c);报错,没有写就就是包访问权限,只能在同一个包中访问
//        System.out.println("不一包中的非子类:" + textDame2.d);报错,被private修饰的只能在当前类被访问
    }
}

7.java中支持的继承的方式

(1)单继承
(2)多层继承
(3)不同类继承同一个类
(4)java不支持多继承

8.final关键字

8.1修饰变量或字段

表示该字段或变量为常量

public class TextDame1 {
    public static void main(String[] args) {
        final int a = 10;
//        a = 20;报错,a被final修饰就是常量了,不能被修改
    }
}

8.2修饰类

该类不能被继承

final class A {

}
//报错,被final修饰的类不能被继承
//class B extends A{
//
//}

8.3修饰方法

该方法不能被重写

class A {
    public final void func(){
        System.out.println();
    }
}
class B extends A{
//    被final修饰的方法不能被重写
//    @Override
//    public void func() {
//    
//    }
}

9.组合

(1)继承是is-a的关系
(2)组合是has-a的关系,和继承类似,组合也是一种表达类之间关系的方式,也是能够达到代码重用的效果,组合仅仅是将一个类的实例作为另外一个类的字段

class A{

}
class B{

}
//组合
class  C{
    private A a;
    private B b;
}

你可能感兴趣的:(Java,java,开发语言)