学习Java的第六天 | 继承 | super | 向上转型 | 方法重写 | 抽象类 | 访问权限修饰符 | 向下转型 |

1 继承

今天来讲类与类之间的关系,前面我们封装了一个猫类,当我们封装一个狗类、鸟类,我们就会发现,在有些属性相同的情况下,get和set有重复,所以我们就会想到要抽离这些重复的代码,我们把这些重复的代码,抽出来,重新定义了一个动物类,这个类拥有了猫类、狗类、鸟类的通用特征,这个动物类就是父类,猫类狗类鸟类就是子类
我们让子类继承父类,拥有父类的特征,在java中,Object类是所有类的顶级父类,而且继承都是单根继承,一个类只能有一个父亲
我们在类名那里,写出继承的代码格式

public class Cat extends Animal{
}

在有继承关系的类中,我们在进行方法调用的时候,会先在自己的类中找有没有这个方法,有就用,没有就向上找父类的方法
如果父类与子类都有相同的方法,想要调用父类的方法的时候,可以使用super调用
如果处在同一条继承链上,他可以调用自己父类和父类以上的类的公共方法

@Override
    public String toString() {
        return super.toString()+
                ", type='" + type + '\'' +
                '}';
    }

2 super

super可以对父类的变量进行调用,但是要注意访问权限修饰符
super();调用父类的构造方法
super();必须放在构造方法的第一句
无参构造方法中,默认有依据super
super可以调用父类的 非私有的方法 和 全局变量

3 向上转型

子类转成父类,称之为向上转型,向上转型,子类对父类隐藏自己的功能
也就是说,当我们用父类的类型来接受子类对象的时候,我们的父类里面本身是没有这个方法的,我们这个父类对象就只能使用父类的方法,但是由于接受的是子类的对象,我们子类的功能还是在,但是被隐藏了

赋值的向上转型

Animal cat = new Cat();
        cat.setName("胖熊");
        cat.setAge(1);
        ((Cat) cat).setType("英短");

传参的向上转型

public static void main(String[] args) {
        Animal cat = new Cat();
        test(cat);
        Animal dog = new Dog();
        test(dog);
    }
    public static void test(Animal cat){
        System.out.println(cat);
    }
输出:
Cat{name='null', age=0, type='null'}
Dog{name='null', age=0, height='null'}

动态绑定: 程序会识别当前数据类型的变量中存放对象的实际类型,并且找到实际类型,执行实际类型中的方法

4 方法重写

子类拥有父类中的方法,但是方法体需要根据自己的类的特征重新书写,就是方法重写 @Override
规则:
1、必须在有继承关系的类之间
2、方法名、参数列表、返回值 都必须相同
3、访问权限的修饰符,子类必须大于等于父类

前面介绍到的toString 方法就是在进行方法重写,我们可以比较一下父子类

@Override
//父类
public String toString() {
    return "Animal{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
}
@Override
//子类
public String toString() {
    return "Cat{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", type='" + type + '\'' +
            '}';
}

我们在Animal Cat Dog 再创建一个类叫move类,如果是在以下例子执行的话:

//动物类
public void move(){
        System.out.println("动物可以跑");
}
//猫类
public void move(){
    System.out.println("胖熊往返跑");
}
//狗类
public void move(){
        System.out.println("狗狗跑很快");
}
public class Test01 {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.move();
        Animal cat = new Cat();
        cat.move();
        Animal dog = new Dog();
        dog.move();
        Test(cat);
        Test(dog);
    }
    public static void Test(Animal cat){
        cat.move();
    }
}

我们就会发现,其实父类的方法体可以省略,反正子类会重写,但是在java中,我们父类的方法体省略,方法声明还是要有
如果一个方法只有方法声明的话,就是 抽象方法
抽象方法的书写格式 就是在返回值前面加 abstract 的关键词

public abstract class Animal {
    
    private String name;
    private int age ;
    
    public abstract void move();
    }
}

5 抽象类

抽象方法一定要在抽象类中
抽象类不一定有抽象方法
抽象类不能创造对象,因为创造对象的话,就要调用方法执行方法体,但是抽象方法中,没有方法体
抽象类中可以有:
属性、setget方法、构造方法、静态代码块、代码块、抽象方法
抽象类的实现可以通过匿名内部类
匿名内部类可以实现多个抽象方法

public class Test01 {
    public static void main(String[] args) {
        Animal animal = new Animal() {
            @Override
            public void run() {
                System.out.println("匿名内部类的animal做的方法实现");
            }

            @Override
            void eat() {
                
            }
        };
        animal.run();
        animal.eat();
    }
}

一个类继承了抽象类,报错的解决方式:
1、重写抽象类中的方法
2、把自己声明为抽象类

6 访问权限修饰符

不同包下的类之间不同包下的有继承关系的类中同一包下的类之间当前类
public
protected
默认
private

测试代码如下:
A和Test01是一个包
B和Test02是一个包

public class Test01 {
    public static void main(String[] args) {
        //同个包下的类
        A a = new A();
        a.name="a";//public
        a.number;//private
        a.nature = "nature";//默认
        a.age = 1;//protected

    }
}
public class A {
    public  String name;
    private int number ;
    String nature ;
    protected int age;
    //当前类
    public void test(){
        System.out.println(name);
        System.out.println(number);
        System.out.println(nature);
        System.out.println(age);
    }
}
public class Test02 {
    public static void main(String[] args) {
        //不同包下的类
        A a = new A();
        a.name="a";//public
        a.number;//private
        a.nature = "nature";//默认
        a.age = 1;//protected

    }
}
public class B extends A {
    public  String name;
    private int number ;
    String nature ;
    protected int age;


    //不同包下有继承关系的类中
    public void test(){
        System.out.println(super.name);
        System.out.println(super.number);
        System.out.println(super.nature);
        System.out.println(super.age);
    }
}

前面提到,子类继承父类,方法重写的时候,子类的修饰符必须大于等于父类

子\父private默认protectedpublic
private
默认
proetected
public

private < 默认 < protected < public

抽象方法修饰符不可以使用private

7 向下转型

我们的向下转型,就是强制父类拥有子类的特征,我们不能在这里进行强制转换,因为这个会显示一个强制转换异常
想要避免这异常,我们可以先进行判断,再来转换

(对象 instanceof 类型)true  不是 false

public class Test01 {
    public static void main(String[] args) {
    	//创建一个家用电器对象
        Appliances a = new Appliances();
        //这个家用电器是不是冰箱
        if (a instanceof Refrigerator){
        	//是 强转为冰箱
            Refrigerator r = (Refrigerator)a;
        }else {
        	//不是  转不了
            System.out.println("类型不匹配,不可转换");
        }
        
    }
}

如果非要向下转型,必须建立在向上转型的基础上
下面考虑到test方法中的else返回字符串,则将接受类型从电器类型Appliances改为它和String的父类,Object

public class Test01 {
    public static void main(String[] args) {
    	//这里使得它返回一个电冰箱对象被Object类接受  向上转型
        Object a = test(0);
        //a这个对象是电视类吗
        if (a instanceof Television){
            //是 向下转型  将a强转为电视类型
            Television t = (Television)a;
            //a这个对象是电冰箱类吗
        }else if (a instanceof Refrigerator){
        	//是 向下转型  将a强转为电冰箱类型 
            Refrigerator r =(Refrigerator)a;
        }else {
        	//都不是 类型不匹配
            System.out.println("类型不匹配");
        }

    }
    public static Object test(int num){
        if (num == 0){
        	//如果是0 那就返回一个电视对象
            return new Television();
        }else if(num == 1)  {
        	//如果不是0 那就返回一个电冰箱对象
            return new Refrigerator();
        }else{
        	return "没有匹配"
        }
    }
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页