Java编程 Javase06

一、多态

  • 面向对象三大特征:封装性、继承性、多态性。

  • extends继承或implements实现,是多态性的前提

(一)多态的概述

  • 例如:小明是一个学生(学生形态),也是一个人(人类形态)。
  • 小明是一个对象,这个对象既有学生形态也有人类形态。
  • 定义一个对象拥有多种形态,这就是对象的多态性

(二)多态的格式与使用

  • 代码当中体现多态性,其实就是:父类引用指向子类对象。

1、格式

父类名称 对象名 = new 子类名称 () ;

或者

接口名称 对象名 = new 实现类名称();

2、多态中成员变量和成员方法的使用

(1)多态中访问成员变量的两种方式(与之前相同):

  • 直接通过对象名称访问成员变量,等号左边是谁,优先用谁,没有则向上查找。
  • 间接通过成员方法进行访问,看该方法属于谁则优先用谁,没有则向上查找。
  • 子类没有覆盖重写方法则使用父类,覆盖重写则使用子类

注意:成员变量不能覆盖重写。

(2)多态中成员方法的使用

  • 看new的是谁,则优先用谁,没有则向上查找。
  • 编译看左边,运行看右边。(成员变量:编译看左边,运行看左边)
public class Fu {
    public void method(){
        System.out.println("父类方法");
    }
    public void methodFu(){
        System.out.println("父类独有!");
    }
}


public class zi extends Fu {
    @Override
    public void method() {
        System.out.println("子类方法");
    }
    public void methodzi(){
        System.out.println("子类独有!");
    }
}


public class Demo04 {
    public static void main(String[] args) {
        //创建一个子类多态对象
        Fu one = new zi();
        //调用子类方法
        one.method();
        //编译看左边,引用的为父类方法,父类方法中没有methodzi方法
        //one.methodzi();
        //运行看右边,子类方法中继承了父类方法
        one.methodFu();
    }
}
输出为:
子类方法
父类独有!

Process finished with exit code 0

(3)多态的好处

  • 无论右边new的时候换成哪个子类对象,等号左边的调用方法都不会变化。
public  abstract class  employee {
    public abstract void work();
}

public class teacher extends employee {
    @Override
    public void work() {
        System.out.println("我来讲课!");
    }
}

public class assistant extends employee {
    @Override
    public void work() {
        System.out.println("我来辅导!");
    }
}


public class Demo04 {
    public static void main(String[] args) {
        //不使用多态将代用多个不同的子类方法
        teacher one =new teacher();
        one.work();
        assistant two =new assistant();
        two.work();
        for (int i = 0; i < 10; i++) {
            System.out.print("==");
        }
        System.out.println("\n");
        //使用多态将只调用一种方法
        employee three = new teacher();
        three.work();
        employee four = new assistant();
        four.work();
    }
}
输出为:
我来讲课!
我来辅导!
====================

我来讲课!
我来辅导!

(4)对象的向上转型

  • 定义:对象的向上转型,其实就是多态写法。(即父类引用指向子类对象)
  • 格式:父类名称 对象名 = new 子类名称 ( ) ;
  • 含义:右侧创建一个子类对象,将它当作父类看待。
  • 注意:向上转型一定是安全的。类似于数据类型的自动转换。

(5)对象的向下转型

  • 向上转型有一定弊端:一旦向上转型为父类,则无法调用子类原本特有的内容。
  • 解决方案:用对象的向下转型【还原】。类似于数据类型的强制类型转换。
  • 格式:子类名称 对象名 =(子类名称)父类对象;
  • 含义:将父类对象还原成为本来的子类对象。
  • 注意:必须保证对象本来创建的时候就是该子类,不能转换为其他子类。
  • public abstract class  Aniamls {
        public  abstract void eat();
        public abstract void sleep();
    }
    
    public class cat extends Aniamls{
        @Override
        public void eat() {
            System.out.println("吃小鱼干!");
        }
    
        @Override
        public void sleep() {
            System.out.println("喵呜~");
        }
        public void catchmouse(){
            System.out.println("抓老鼠!");
        }
    }
    
    public class Demo04 {
        public static void main(String[] args) {
            Aniamls xiaoju=new cat();
            //向下转化
            cat cat1= (cat) xiaoju;
            cat1.catchmouse();
        }
    }
    
    //输出为:抓老鼠!

(6)用instanceof关键字进行类型判断

  • 即判断父类引用的对象,本来是什么子类,通常用于向下转型的类型判断。

格式:对象 instanceof 类型

  • 这将会得到一个Boolean值结果,也就是判断前面的对象能不能当作后面类型的实例
public class pet {
    public static void main(String[] args) {
        pet(new cat());
        for (int i = 0; i < 20; i++) {
            System.out.print("=");
        }
        System.out.println("\n");
        pet(new dog());
    }

    public static void pet(Aniamls animal) {
        //使用instanceof关键字判断类型
        if (animal instanceof cat) {
            cat cat = (cat) animal;
            cat.catchmouse();
            cat.eat();
        }
        if (animal instanceof dog) {
            dog dog = (dog) animal;
            dog.eat();
            dog.sleep();
        }
    }
}
输出为:
抓老鼠!
吃小鱼干!
====================

吃骨头
呼噜噜.......

(三)笔记本USB接口案例

1、问题:定义USB接口,具备最基本的开启功能和关闭功能,鼠标和键盘要想在电脑上使用,那么鼠标和键盘也必须遵守USB规范,实现USB接口,否则鼠标和键盘生产出来无法使用。

2、分析

3、代码实现

//定义一个USB接口
public interface USB {
    public abstract void open();
    //打开设备
    public abstract void close();
    //关闭设备
}
//定义一个鼠标类
public class mouse implements USB{
    @Override
    public void open() {
        System.out.println("已接入鼠标。");
    }

    @Override
    public void close() {
        System.out.println("已拔出鼠标。");
    }
    public void name(String name){
        System.out.println("这款鼠标的型号为:"+name);
    }
}
//定义一个键盘类
public class keyborad implements USB {
    @Override
    public void open() {
        System.out.println("已接入键盘。");
    }

    @Override
    public void close() {
        System.out.println("已拔出键盘。");
    }
    public void keyname(String name){
        System.out.println("这款键盘的型号为:"+name);
    }
}
//定义一个笔记本类
public class laptop {
    public void type(String name){
        System.out.println("这款笔记本电脑的型号为:"+name);
    }
    public void poweron(){
        System.out.println("您的电脑,正在开机,请稍后。");
        for (int i = 1; i <=10 ; i++) {
            System.out.print(i+"s"+"\t");

        }
        System.out.println("\n您的设备已开机,欢迎使用。");
    }
    public void poweroff(){

    System.out.println("您的电脑,正在关机,请稍后。");
        for (int i = 1; i <=5; i++) {
        System.out.print(i+"s"+"\t");

    }
        System.out.println("\n您的设备已关机,谢谢使用。");
}
    public void laptophard(USB usb){
        if (usb instanceof mouse){
           usb.open();
           usb.close();
        }
        if(usb instanceof keyborad)
        {
            usb.open();
            usb.close();
        }
    }
}
//创建一个对象
public class mylaptop {
    public static void main(String[] args) {
        //创建一个笔记本对象
        laptop mylaptop=new laptop();
        mylaptop.type("拯救者2020Y7000P");
        mylaptop.poweron();
        USB mymouse=new mouse();
        mouse my=(mouse) mymouse;
        my.name("罗技350");
        USB mykeborad=new keyborad();
        keyborad mykey=(keyborad) mykeborad;
        mykey.keyname("牧马人2000");
        mylaptop.laptophard(mymouse);
        mylaptop.laptophard(mykeborad);
        mylaptop. poweroff();
    }
}
输出为:

这款笔记本电脑的型号为:拯救者2020Y7000P
您的电脑,正在开机,请稍后。
1s	2s	3s	4s	5s	6s	7s	8s	9s	10s	
您的设备已开机,欢迎使用。
这款鼠标的型号为:罗技350
这款键盘的型号为:牧马人2000
已接入鼠标。
已拔出鼠标。
已接入键盘。
已拔出键盘。
您的电脑,正在关机,请稍后。
1s	2s	3s	4s	5s	
您的设备已关机,谢谢使用。

Process finished with exit code 0

二、final关键字

(一)final关键字的概念及四种用法

1、final关键字的概念

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

2、四种用法

  • 修饰一个类
  • 修饰一个方法
  • 修饰一个局部变量
  • 修饰一个成员变量

(二)四种用法的使用

1、修饰一个类

  • 任何一个类都是Object的子类
  • 格式:public final class 类名称 { ...}
  • 含义:当前这个类不能有任何的子类,但可以拥有父类。
  • 注意:一个类如果是final类,那么其中的成员方法都无法进行覆盖重写,但可以对其父类进行覆盖重写

2、修饰一个方法

  • 当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
  • 格式:修饰符 final 返回值类型 方法名称 (参数列表){...}
  • 注意:对于类、方法来说,abstract关键字和final关键字不能能够同时使用,因为两者矛盾。

3、修饰一个局部变量

  • 局部变量:方法中使用的变量,方法的参数也属于局部变量
  • 一旦使用final用来修饰局部变量,那么这个变量就不能再进行更改,即使用final关键字进行修饰后,只能进行一次赋值且之后不可改变。
  • 对于基本类型来说,不可变说的是变量当中的数据不可改变。
  • 对于引用类型来说,不可变说的是变量当中的地址值不可改变,但可以改变其中的内容。

例如:

public class name {
    private String name;
    private int age;

    public name(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class main {
    public static  void main(String[] args) {
        name name1=new name("zhangsan",18);
        System.out.println(name1.getName()+" "+name1.getAge());
        System.out.println(name1);
        name1=new name("lisi",19);//未用final修饰时,地址值可以改变
        System.out.println(name1.getName()+" "+name1.getAge());
        final name name2=new name("wangmazi",20);
        System.out.println(name1);
        //name2=new name("zhangwu",12)
        //使用final修饰后地址值不可变,但其中的内容可以改变
        name2.setName("wangwu");
        name2.setAge(21);
        System.out.println(name2.getName()+" "+name2.getAge());
    }
}
输出为:
zhangsan 18
Demo01.name@12edcd21
lisi 19
Demo01.name@34c45dca
wangwu 21

Process finished with exit code 0

4、修饰一个局部变量

  • 对于成员变量来说,final关键字修饰后,这个变量也照样不可改变。
  • 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
  • 对于final的成员变量来说,要么使用直接复制,要么通过构造方法赋值。
  • 必须保证类当中的所有重载的构造方法,都最终会对final的成员变量进行赋值。

例如:

public class students {
    final private String name;
    final private int age=18;
    //使用final修饰后,在构造方法中赋值,且不能使用setter方法
    public students() {
        name = "zhangssan";
    }

    public String getName() {
        return name;
    }
    public int getAge(){
        return age;
    }
}
public class main1 {
    public static void main(String[] args) {
        students stu = new students();
        System.out.println(stu.getName()+' '+stu.getAge());
    }
}
//输出为:zhangsan 18

5、四种权限修饰符

四种修饰符/不同场景访问publicprotected(default)private
同一个类(我自己)YESYESYESYES

同一个包(我邻居)

YESYESYESNO
不同包子类(我儿子)YESYESNONO
不同包非子类(陌生人)YESNONONO
  • 注意:不同包访问类需要进行导包,使用import语句

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值