JavaSE学习之--继承和多态(二)

简介: JavaSE学习之--继承和多态(二)

JavaSE学习之--继承和多态(一)+https://developer.aliyun.com/article/1413489

5.再谈初始化

 先回顾一下静态代码块,实例代码块,构造方法之间执行的先后顺序!

class Test {
    int a;
    // 构造方法
    public Test() {
        System.out.println("这是构造方法!!!");
    }
    // 静态块
    static {
        System.out.println("这是静态代码块!!!");
    }
    // 实例代码块
    {
        System.out.println("这是实例代码块!!!");
    }
}
public class Test1 {
    public static void main(String[] args) {
        Test test1 = new Test();
        System.out.println("=============");
        Test test2= new Test();
    }
}

执行结果:

总结:执行顺序-->静态代码块-->实例代码块-->构造方法

且静态代码块只会被执行一次

那如果既有父类的代码块和构造方法,又有子类的代码块和构造方法,执行顺序是怎样的呢?

先看代码:

class Test {
    int a;
    // 父类的构造方法
    public Test() {
        System.out.println("这是构造方法!!!");
    }
    // 父类的静态块
    static {
        System.out.println("这是静态代码块!!!");
    }
    // 父类的实例代码块
    {
        System.out.println("这是实例代码块!!!");
    }
}
class DTest extends Test {
    // 子类的构造方法
    public DTest() {
        System.out.println("这是子类的构造方法!!!");
    }
    // 子类的静态代码块
    static {
        System.out.println("这是子类的静态代码块!!!");
    }
    // 子类的代码块
    {
        System.out.println("这是子类的代码块!!!");
    }
}
public class Test1 {
    public static void main(String[] args) {
        DTest test1 = new DTest();
        System.out.println("=============");
        DTest test2= new DTest();
    }
}

执行结果:

执行顺序:

1.父类,子类的静态代码块

2.父类实例代码块,构造方法

3.子类的实例代码块,构造方法

所有的静态代码块无论实例化多少个对象都只会被执行一次!!!

6.protected关键字

 为了实现封装特性,引入了访问修饰限定符,不同的关键字有不同的权限

 protected是“受保护的”,它的权限是可以在同包不同类访问,也可以在不同包但是此包的类是另一个包中类的子类,也就是两个包之间的类存在继承关系!

1.同一个包不同类中成员的访问

class B {
    private int a;
    int b;
    protected int c;
    public int d;
}
class C extends B {
    // 同一个包不同类
    public void method() {
        super.a = 20;// err,private成员不能跨类访问
        super.b = 20;// 默认权限的成员可以跨类访问
        super.c = 20;// protected成员可以跨类访问
        super.d = 20;// public成员可以跨类访问
    }
}

2.不同包不同类中成员的访问

class B {
    private int a;
    int b;
    protected int c;
    public int d;
}
// 不同包但存在继承关系之间成员的访问
class C extends B {
    public void method2() {
        super.a = 20;// err private成员不能跨类访问
        super.b = 20;// err 默认权限成员不能跨包访问
        super.c = 20;// protected成员在子类中可以访问
        super.d = 20;// public成员可以跨包访问
    }
}

注意不要忘记引入父类的包:

总结:

1.继承是可以跨包的,如果另一个包中类是另一个包中的类的子类,则存在继承关系;子类会继承父类所有的成员和方法(但是不能全部访问,这取决于父类中成员或方法的访问权限)

2.我们有这么多的权限,那什么时候用什么权限呢?前期学习,大家都会使用一种粗暴的方法,把所有的成员设置为private,所有的方法设置为public,在前期对权限理解不深的时候我们可以这样设置,但使用哪个权限还是要具体问题具体分析,这取决于你对成员或方法的需求!

7.Java中的继承关系(三种)

8.final关键字

 final关键字可以修饰变量,方法,类

1.修饰变量会使变量不能被修改(成为常量)

final int b = 20;
        b = 30;// err b是常量,无法修改常量的值

2.修饰类,代表此类无法被继承

final class B {
    private int a;
    int b;
    protected int c;
    public int d;
}
// 此时B就无法被继承
class C extends B {
}

平常我们使用的String类就是被final修饰的

3.修饰方法,此方法无法被重写

9.继承与组合

 继承反映的是类与类之间的关系,同样的,组合 也是一种反应类与类关系的一种思想!

它代表一个类可以由多个类组成,比如一个Person类可以由Leg,Nose,Head类组成,不同于继承的是组合并没有关键字,只需在类中包含其他类就可以实现类的组合,请看下面代码:

class Nose{};
class Head{};
class Leg{};
class Person{
    private Nose nose;// 可以复用Nose类中的方法和属性
    private Head head;// 可以复用Head类中的方法和属性
    private Leg leg;// 可以复用Leg类中的方法和属性
}
class Stu extends Person{
    // 继承了人的鼻子,头,腿
};

二.多态

多态就是通过父类引用不同对象,调用同一个重写的方法时,所表现的行为不同(所产生的结果不同),这种现象就叫做多态!

要理解多态,需要理解几个基本概念:向上转型,重写,向下转型,动态绑定

1.向上转型

1.向上转型的定义:

   父类引用引用子类对象就叫做向上转型(子类对象被父类引用)

class Animal{};
class Dog extends Animal{};
class Cat extends Animal{};
public class Test {
    public static void main(String[] args) {
        // 向上转型
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

2.实现向上转型的三种方式

1.直接赋值

2.方法传参

3.方法返回

1.直接赋值
Animal animal1 = new Dog();
        Animal animal2 = new Cat();
2.方法传参

   将方法形参设置为父类引用,实参是子类对象,通过调用方法实现将父类引用指向子类对象!

class Animal{
    public void makeSound() {
        System.out.println("动物发出叫声!");
    }
};
class Dog extends Animal{
    @Override
    public void makeSound() {
        System.out.println("小狗在汪汪叫!");
    }
};
//class Cat extends Animal{};
public class Test {
    public static void animalMakeSound(Animal animal) {
        animal.makeSound();
    }
    public static void main(String[] args) {
        Animal mydog = new Dog();
        animalMakeSound(mydog);
    }

       在main方法中我们创建了一个Dog对象,并将其向上转型为Animal类型,接着在animalMakeSound方法中调用该对象,让父类引用指向该对象,在方法内部实现了向上转型!

   通过上述代码我们可以看出,将形参设置为父类引用最大的好处就是增加了代码的通用性!因为实参可以是任意子类对象

JavaSE学习之--继承和多态(三)+https://developer.aliyun.com/article/1413491

目录
相关文章
|
8月前
|
Java 编译器
【JAVASE】继承 中
【JAVASE】继承
|
4月前
|
Java 编译器
JavaSE学习之--继承和多态(三)
JavaSE学习之--继承和多态(三)
39 0
|
4月前
|
Java 编译器
JavaSE学习之--继承和多态(一)
JavaSE学习之--继承和多态
39 0
|
4月前
|
存储 Java 机器人
JavaSE学习之--抽象类,接口,内部类(二)
JavaSE学习之--抽象类,接口,内部类(二)
36 0
|
4月前
|
Java
JavaSE学习之--抽象类,接口,内部类(一)
JavaSE学习之--抽象类,接口,内部类(一)
61 0
|
4月前
|
存储 Java 编译器
JavaSE学习之--抽象类,接口,内部类(三)
JavaSE学习之--抽象类,接口,内部类(三)
28 0
|
10月前
|
Java 程序员 编译器
【JavaSE】一起学继承
【JavaSE】一起学继承
|
5月前
|
安全 Java 程序员
JavaSE继承和多态
JavaSE继承和多态
|
5月前
|
Java 程序员 编译器
【JavaSE】面向对象之继承
【JavaSE】面向对象之继承
|
8月前
|
Java 程序员
【JAVASE】继承 上
【JAVASE】继承