java基础day15---重写--多态--转型

day15

class Animal{
    //属性
    String name;
    int age;
    String color;
    //方法:显示信息
    public void show(){
        System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color);
    }
}
//编写狗的子类继承动物父类
class Dog extends Animal{
    //编写子类中独有属性和方法
    String strain;、
    //重写也叫做覆盖override:在子类中重写父类的方法,必须与父类的方法名称一致,参数列表一致、返回类型一致、修饰符一致
    public void show(){
        //在子类可以直接访问父类中的属性(前提:父类中属性没有使用private修饰)
        System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color+"\n品种:"+strain);
    }

}
//等价于
/*class Dog extends object{

}*/

class Cat extends Animal{
    //独有属性:性别
    char sex;
}


1.重写
----子类方法名称必须与父类方法名称一致
---参数列表一致
---返回类型一致或父类方法返回类型的子类类型
---修饰符不能缩小范围
子类不能重写:
---构造方法不能重写
---属性不能重写
---静态方法不能重写
---私有方法不能重写

//编写测试类
class Test{
    public static void main(String[] args){
    //创建狗的对象
    Dog d=new Dog();
    //显示信息
    d.show();//先在Dog类中找show方法,如果没有找到则再去父类中找

    }
}



2.this与super关键字访问实例变量区别
this 关键字---代表当前这个对象
---this可以访问本类中的实例变量,实例方法也可以访问本类中
的其他构造方法
---this还可以访问父类中的实例变量
super关键字---表示超类
---super只能在子类中使用,可以访问父类中的实例变量

注意:--如果访问实例变量时,默认前面添加this,但是使用this.访问实例变量时
先在当前类中找该属性
--使用super直接去父类中找该属性或方法
--使用super访问父类的构造方法

class Student extends Person{
    //无参构造
    public Student(){
    }
    public Student(String name,char sex,int age,int id){
    super(name,sex,age);//父类构造了此方法,直接调用
    this.id=id;
    }
}



3.当实例化子类时父类做了什么?
--先执行父类的构造方法,然后再执行子类的相匹配构造方法
---如果子类构造方法中没有指名则默认调用父类的无参构造方法;
---如果子类构造方法中指明调用父类哪个构造方法,则先执行父类
相匹配的构造方法,然后再执行子类相匹配构造方法。

建议:--当手动编写构造方法时,先编写无参构造方法,再编写
    所需要的构造方法。

/*
某个汽车租赁公司有多种紫车可以出租,计算汽车的租金
Vehicle是所有车的父类,属性:品牌,车牌号
方法:返回总租金的方法:public double getSumRent(int days){}
Car:小汽车类是Vehicle的子类,属性:车型(两厢,三厢,越野)
两厢:每天300,三厢:每天350,越野:每天500
Bus:多座汽车,属性:座位数
座位数<=16:每天400
座位数>16:每天600
测试类:
根据用户选择不同,计算总租金并输出总租金

*/
class Vehicle{
    //属性
    String brand;
    String id;
    //构造方法
    public Vehicle(){
    
    }
    public Vehicle(String brand,String id){
        this.id=id;
        thid.brand=brand;
    }
    //方法:返回总租金的方法
    public double getSumRent(int days){
        return 0;
    }
}
//编写小轿车子类继承车的父类
class Car extends Vehicle{
    //编写独有属性
    String type;
    //构造方法
    public Car(){
        super();
        this.type="三厢";
    }
    public Car(String brand,String is,String type){
        super(brand,id);
        this.type;
    }
    //重写父类的总租金方法
    public double getSumRent(int days){
    //判断,根据车型获取日租金
    switch(this.type){//注意:当type属性没有赋值时,该值为null,在java中,switch表达式中如果为null,就会出现空指针异常
    case "两厢":
        return 300 * days;
    case "三厢":
        return 350 * days;
    default:
        return 500 * days;
      }
    }
}
//编写小轿车测试类
class CarTest{
    public static void main(String[] args){
    //实例化小轿车
    Car c=new Car();
    System.out.println("总租金:"+c.getSumRent(3));
    }
}



4.多态:
---多态语法格式:
--父类类名 引用名称=new 子类类名();
--当是多态时,该引用名称只能访问父类中的属性和方法,
    但是优先访问子类重写以后的方法;
---多态:将多个对象调用一个方法,得到不同的结果;
---满足多态的条件:
--子类必须继承父类;
--子类重写父类的方法;
--父类类名 引用名称=new 子类类名();

class Test{
    /*
    多态的语法格式:
        父类类名 引用名称=new 子类类名();
    注意:当是多态时,该引用名称只能访问父类中的属性和方法啊,但是优先访问子类重写以后的方法

    */
    Vehicle c=new Car();
    System.out.println(c.brand);//null
    System.out.println(c.id);null
    //System.out.println(c.type);//出现编译错误,因为引用名称c是父类类型,因此只能访问父类中的属性
    c.print();//ok,在父类中定义了此方法
    System.out.println(c.getSumRent(1));
}



5.多态的好处:减少代码的冗余性

6.为什么要进行类型的转换:
---多态中的两种类型转换
--向上转型:也叫做自动类型转换
    父类类型 引用名称=new 子类类名();

--向下转型:也叫做强制类型转换
    当是多态时,并且访问子类独有的属性或方法,则必须进行
    向下转型

实例:

class Pet{
//方法
    public void eat(){
        System.out.println("宠物正在吃东西.....");
    }
}
//编写狗的子类继承宠物父类
class Dog extends Pet{
//重写父类的eat方法
    public void eat(){
        System.out.println("狗正在吃狗粮....");
    }
    //编写独有的方法:玩飞盘
    public void play(){
        System.out.println("狗正在玩飞盘....");
    }
}
//编写猫的子类继承宠物父类
class Cat extends Pet{
    //重写父类的吃的方法
    public void eat{
        System.out.println("猫正在吃猫粮....");
    }
    //编写独有的方法:抓老鼠
    public void catching(){
        System.out.println("猫正在抓老鼠....");
    }
}
//编写主人类
class Master{
//方法:喂养狗
    /*public void feed(Dog dog){
    dog.eat();
    }
    public void feed(Cat cat){
    cat.eat();
    }*/
    /*
    总结得到:以上喂养猫和狗都属于宠物,因此能否编写主人喂养宠物方法

    */
    public void feed(Pet pet){//Pet pet=new Dog();  Pet pet=new Cat()
        pet.eat();
    }
}
//测试类
class Test{
    public static void main(String[] args){
        //创建主人对象
        Master m=new Master();
        //创建狗对象
        Dog d=new Dog();
        //主人喂养宠物
        m.feed(d);

        m.feed(new Cat());
    }    
}
class Test2{
    public static void main(String[] args){
    Pet p=new Dog();//构成多态;也就是说向上转型
    /*p.eat();
    //p.play();// 出现编译错误,父类类型不能访问子类独有属性或方法
    //解决办法:进行向下转型
    Dog d=(Dog)p;
    //此时就可以使用引用名称d访问狗中的play方法
    d.play();
    
    */
    /*Cat c=(Cat)p;//出现运行错误,原因:当前引用名称p存放的是狗对象的地址,因此不能强制转换为猫
    c.catching();*/
    //解决办法:当进行向下转型时,建议先进行判断,当合法则在转为对应的类型,则使用instanceof关键字
    p=new Cat();
    if(p instanceof Dog){
        Dog dog=(Dog)p;
        dog.play();
    }else if(p instanceof Cat){
    Cat cat=(Cat)p;
    cat.catching();
    }
    }
}



猜你喜欢

转载自www.cnblogs.com/fdxjava/p/10666570.html