java笔记

对象的向上转型

1.对象的向上转型。其实就是多态写法:

格式:父类名称 对象名 = new 子类名称(); Animal animal = new Cat();

含义:右侧创建—个子类对象,把它当做父类来看待使用。 创建了一只猫,当做动物看待,没问题。

注意事项:向上转型一定是安全的。从小范围转向了大范围,从小范围的猫,向上转换成为更大范围的动物。

类似于:

double num = 100; //正确,int --> double,自动类型转换。

对象的向下转型

2.对象的向下转型,其实是一个【还原】的动作。

格式:子类名称 对象名 =(子类名称) 父类对象; Cat cat = (Cat) animal;

含义:将父类对象,【还原】成为本来的子类对象。 本来是猫,已经被当做动物了,还原回来成为本来的猫

注意事项:

a.必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。

b.如果对象创建的时候本来不是猫,现在非要向下转型成为猫。就会报错。

类似于:

int num =(int)10.0;//可以 int num =(int)10.5//精度损失

public abstract class Animal {
    public abstract  void eat();
​
}
==============================================
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouser(){
        System.out.println("猫抓老鼠");
    }
}
===============================================
public class Demo01Man {
    public static void main(String[] args) {
        //对象的向上转型,就是:父类引用指向之类对象
        Animal animal = new Cat();
        animal.eat();//猫吃鱼
        //animal.catchMouser(); 错误写法!
​
        //向下转行,进行“还原”动作
        Cat cat = (Cat) animal;
        cat.catchMouser();//猫抓老鼠
        //下面是错误的向下转型
        //本来new的时候是一只猫,现在非要当中狗
        //错误写法!编译不会报错,但是运行会出现异常,
        // java.lang.ClassCastException  类转换异常
        Dog dog = (Dog) animal;
    }
}
=================================================
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void watchHouse(){
        System.out.println("狗看家");
    }
}

用instanceof关键字进行判断

public class Demo01Instanceof {
    public static void main(String[] args) {
        Animal animal = new Cat();//本来是一只猫
        animal.eat();//猫吃鱼
        //如果希望调用子类特有方法,需要向下转型
        //判断一下父类引用animal本来是不是Dog
        if(animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        //判断一下父类引用animal本来是不是Cat
        if(animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.catchMouser();
        }
        Dexter(new Dog());
    }
    public static void Dexter(Animal animal){
        if(animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        //判断一下父类引用animal本来是不是Cat
        if(animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.catchMouser();
        }
    }
}
猫吃鱼
猫抓老鼠
狗看家

接口多态的综合案例USB

public interface USB {
    public abstract void open();//打开设备
    public abstract void close();//关闭设备
}
public class Computer {
    public void powerOn(){
        System.out.println("笔记本电脑开机");
    }
    public void powerOff(){
        System.out.println("笔记本电脑关机");
    }
    //使用USB设备的方法,使用接口作为方法的参数
    public void userDevice(USB usb){
        usb.open();
        if(usb instanceof Mouse){//先判断
            Mouse mouse = (Mouse) usb;//向下转型
            mouse.click();
        }else if(usb instanceof Keyboard){//先判断
            Keyboard keyboard = (Keyboard) usb;//向下转型
            keyboard.type();
        }
        usb.close();
    }
}
public class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("打开鼠标");
    }
​
    @Override
    public void close() {
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("鼠标点击");
    }
}
public class Keyboard implements USB{
    @Override
    public void open() {
        System.out.println("打开键盘");
    }
​
    @Override
    public void close() {
        System.out.println("关闭键盘");
    }
    public void type(){
        System.out.println("键盘输入");
    }
}
​
public class DemoMain {
    public static void main(String[] args) {
        //首先创建一个笔记本电脑
        Computer computer = new Computer();
        computer.powerOn();
        //首先进行向上转型
        USB usbMouse = new Mouse();//多态写法
        //参数是USB类型,传递进去的就是USB鼠标
        computer.userDevice(usbMouse);
        //首先创建一个USB键盘
        Keyboard keyboard  = new Keyboard();//没有使用多态写法
        //参数是USB类型,传递进去的是实现类对象
        computer.userDevice(keyboard);//正确写法,也是向上转型
        computer.userDevice(new Keyboard());//也是正确写法
        computer.powerOff();
    }
}

final 关键字

final关键字代表最终、不可改变的。

常见四种用法:

1.可以用来修饰一个类

2.可以用来修饰一个方法

3中还可以用来修饰一个局部变量

4.还可以用来修饰─个成员变量

final 关键字用来修饰一个类

格式:

public final class 类名称 {
    //.......
}

含义:当前这个类不能有任何的子类。

注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没子类)

final 关键字用来修饰成员方法

当于final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。

格式:

修饰符 final 返回值类型 方法名称(参数列表) {
    //方法体
}

注意事项:

对于类、方法来说, abstract关键字和final关键字不能同时使用,因为矛盾。

public abstract final void method(); 
//错误写法 abstract 就是要被覆盖重写  而fianl就是不能被覆盖重写

final 关键字用来修饰局部变量

对于基本类型来说,不可变说的是变量当中的数据不可改变

—旦使用finaL用来修饰局部变量,那么这个变量就不能进行更改。
“一次赋值,终生不变”
final int num1 = 200;
System.out.println(num1);//200
num1 = 250;//错误写法
num1 = 200; //错误写法

对于引用类型来说,不可变说的是变量当中的地址值不可改变

final Student stu1 = new Student("张艺兴")
    //错误写法 fianl的引用类型变量,其中的地址不可改变
    //stu1 = new Student("张子枫");
	System.out.println(stu1.getname());//张艺兴
	stu1.setName("张子枫");
	System.out.println(stu1.getname());//张子枫

final 关键字用来修饰成员变量

对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。

1.由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。

2.对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。

3.必须保证类当中所有重载的构造方法,都最终会对于final的成员变量进行赋值。

上一篇:2021-07-06继承


下一篇:Java多态——概念