2021-03-07:java第11天:多态,final关键字,四种权限修饰符

1.对象的多态性

对象的多态举例:

package Day_12;

public class Fu {
    public void method(){
        System.out.println("父类方法");
    }
}

package Day_12;

public class Zi extends Fu{
    @Override
    public void method(){
        System.out.println("子类方法");
    }
}

package Day_12;
//demo01polymorphism
/*
代码当中体现多态性,就是父类引用指向子类对象
父类名称 对象名 = new 子类名称()
接口名称 对象名 = new 实现类名称()
 */
public class demo01Multi {
    public static void main(String[] args) {
        Fu obj = new Zi();
        //左侧父类的引用指向右侧子类的对象
        obj.method();//就近原则,这里是调用子类的方法
        //子类没有这个方法才继续往上找

    }
}

2.对象的多态,成员变量和方法的规则:

package Day_12.demo02;

public class Fu {
    int num = 10;
    public void showNum(){
        System.out.println(num);
    }
}

package Day_12.demo02;

public class Zi extends Fu{
    int num = 20;
    int age = 16;
    @Override
    public void showNum(){
        System.out.println(num);
    }
}

package Day_12.demo02;
/*
访问成员变量的两种方式:
1.直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找
2.间接通过成员方法访问成员变量,看该方法属于谁优先用谁(new的是谁),没有则向上找
 */
public class demo01MultiField {
    public static void main(String[] args) {
        //使用多态的写法,父类引用指向子类对象
        Fu obj = new Zi();
        //成员变量是不能覆盖重写的,只有成员方法可以覆盖重写
        System.out.println(obj.num);//打印父类里的成员变量
        //System.out.println(obj.age);父类里没有,只能往上找,但往上也没有,所以报错
        //子类没有覆盖重写,就是父
        //子类如果覆盖重写,就是子
        obj.showNum();
    }
}

口诀:编译看左边,运行看右边

成员变量不在此列

成员变量:编译看左边,运行还看左边

成员方法:编译看左边,运行看右边

 

3.使用多态的好处:

4.对象的向上,向下转型

package Day_12.demo03;

public abstract class Animal {
    public abstract void eat();
}

package Day_12.demo03;

public class Cat extends Animal{
    @Override
    public void eat(){
        System.out.println("猫吃鱼");
    }
    //子类特有方法
    public void catMouse(){
        System.out.println("猫爪老鼠");
    }
}

package Day_12.demo03;

public class Dog extends Animal{
    @Override
    public void eat(){
        System.out.println("狗吃shit");
    }
    public void watchHouse(){
        System.out.println("狗看家");
    }
}


package Day_12.demo03;
/*
向上转型一定是安全的,但是有弊端,
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容

解决方法:用对象的向下转型【还原】
 */

public class demo01Main {
    public static void main(String[] args) {
        //对象的向上转型,就是父类引用指向子类对象
        Animal animal = new Cat();
        //此时对象调用子类里有的方法,父类里抽象出来
        animal.eat();
        //animal.catchMouse();错误写法

        //向下转型进行还原:
        Cat cat =(Cat) animal;
        cat.catMouse();

        //下面是错误的向下转型
        Dog dog = (Dog) animal;//会出错,ClassCastException.
        //编译不会报错,但是运行会出现异常
    }
}

拿到一个父类的引用,如何知道是父类

package Day_12.demo03;
/*
如何才能知道一个父类引用的对象,本来是什么子类
格式:
对象 instanceof 类型
者将会得到一个boolean值结果,也就是判断前面的对象能不能当作后面类型的实例

 */
public class demo02Instanceof {
    public static void main(String[] args) {
        Animal animal = new Cat();//本来是一只猫
        animal.eat();
        //如果希望调用子类特有方法,向下转型
        //判断一下父类引用animal本来是不是Dog
        
        giveMeAPet(new Dog());
    }

    public static void giveMeAPet(Animal animal) {
        if (animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        if (animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.catMouse();
        }
    }
}

5.笔记本USE接口案例

代码实现:

package Day_12.demo04;

public class Computer {
    public void powerOn(){
        System.out.println("笔记本电脑开机");
    }
    public void powerOff(){
        System.out.println("笔记本电脑关机");
    }
    //使用USB设备的方法,使用接口作为方法的参数
    public void useDevice(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();
    }
}


package Day_12.demo04;

public interface USB {
    public abstract void open();
    public abstract void close();
}



package Day_12.demo04;
//键盘是一个USB设备
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("键盘输入");
    }
}

package Day_12.demo04;
//鼠标是一个USB设备
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("点击鼠标");
    }
}


package Day_12.demo04;

public class demoMain {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();
        //Mouse mouse = new Mouse();
        //USB usb = mouse;
        //准备一个鼠标
        //首先进行向上转型,多态写法
        USB usbmouse = new Mouse();
        computer.useDevice(usbmouse);

        //键盘,没有使用多态写法也是对的
        Keyboard keyboard = new Keyboard();
        //方法参数是USB类型,传递进去的是实现类对象
        computer.useDevice(keyboard);

        computer.powerOff();

        method(10.0);//正确写法 double -->double
        method(10); //正确写法:int --> double
    }

    public static void method(double num) {
        System.out.println(num);
    }
}



6.final关键字概念与4种用法:

package Day_12.demo05;
/*
final关键字代表最终、不可改变的
常见四种用法:
1.可以用来修饰一个类
2.可以用来修饰一个方法
3.还可以用来修饰一个局部变量
4.还可以用来修饰一个成员变量
 */
public class demo01final {
    public static void main(String[] args) {
        int num1 = 10;
        System.out.println(num1);
        num1 = 20;
        System.out.println(num1);
        //一旦使用final修饰局部变量,不能进行更改
        //一次赋值终生不变
        final int num2 = 200;

        final int num3;
        num3 = 30;//只要保证一次赋值

        //对于基本类型来说,不可变说的是变量当中的数据不可改变
        //对于引用类型来说,不可变说的是变量当中的地址值不可改变
        final Student stu1 = new Student("赵丽颖");
        System.out.println(stu1.getName());
        //stu1 = new Student("霍建华");
        //System.out.println(stu1.getName());
        //stu1如果加上final,其中地址不能改变,不能二次赋值
        //然而,地址里面的东西可以变
        stu1.setName("高圆圆");
        System.out.println(stu1.getName());
    }
}

//修饰一个类:

package Day_12.demo05;
/*
当final关键字用来修饰一个类:格式
public final class 类名称{}
含义:当前这个类不能有任何子类,(太监类)
    但有父类
注意:一个类如果是final类,那么其中所有的成员方法都无法进行覆盖重写(没儿子)

 */
public final class Myclass /*extends Object*/{
    public void method(){
        System.out.println("方法执行");
    }
}

package Day_12.demo05;
//不能用final类作为父类
public class Mysubclass /*extends Myclass*/{
}

修饰一个方法:

package Day_12.demo05;
/*
当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写
格式:
修饰符 final 返回值类型 方法名称(参数列表){}
注意事项:
对于类,方法来说,abstract关键字和final关键字不能同时使用,因为矛盾
 */
public abstract class Fu {
    public final void method(){
        System.out.println("父类方法执行");
    }
    public abstract/*final*/ void methodAbs();
}

package Day_12.demo05;

public class Zi extends Fu{
    @Override
    public void methodAbs() {

    }
    //子类当中不能覆盖重写父类有final关键字的方法
    /*@Override
    public void method(){
        System.out.println("子类覆盖重写父类的方法");
    }*/


}

修饰一个成员变量:

package Day_12.demo05;
/*
基本类型作为类的成员时会有默认值
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变
1.由于成员变量有默认值,用了final之后必须手动赋值
2.对于final的成员变量要么使用直接赋值,要么通过构造方法赋值,二者选其一
3.必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
主程序的
 */
public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }
}

package Day_12.demo05;

public class Student {
    private String name;

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Student(String name) {
        this.name = name;
    }
}

7.四种权限修饰符

package Day_12.demo06;
/*
Java种有四种权限修饰符:
    public > protected > (default) > private
同一个类(我自己) yes    yes          yes         yes
同一个包(我邻居) yes    yes          yes         no
不同包子类(我儿子)yes    yes          no         no
不同包非子类(陌生人)yes    no          no         no
 */
public class demo01Main {
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值