JavaSE学习笔记(五)

多态
extends继承 implements实现 是多态的前提
【类与类的继承 接口与接口的继承 类与接口之间的实现】
总之,有上下关系是多态的前提

人(父类)----------学生(子类)、员工(子类)
小明是一个学生(学生形态)也是一个人(人类形态)
小明是一个对象,既有学生形态也有人类形态,一个对象有多个形态,这就是对象的多态性

多态格式:
父类名称 对象名 = new 子类名称();
接口名称 对象名 = new 实现类名称();

public class Fu {
    public void metod(){
        System.out.println("父类方法");
    }
    public void metod1(){
        System.out.println("父类特有方法");
    }
}

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

public class Demo {
    public static void main(String[] args) {
        Fu obj = new Zi();               //多态
        obj.metod();
        obj.metod1();
    }
}

===============================================
多态访问成员变量
1.直接方法,对于成员变量的访问,看等号左边是谁,就到那个类里去找
2.间接方法,对于成员方法,看属于谁,就先到那个类里找,没有则向上找。

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

public class Zi extends Fu{
    int num=20;
    int ages=200;

}

public class Demo {
    public static void main(String[] args) {
        Fu obj = new Zi();
		
        System.out.println(obj.num);//直接去找

        //System.out.println(obj.ages);    错误,先到Fu类去找,没有则想上找,不会向下(Zi)找

        obj.NUM(); //间接去找
    }
}

====================================================
多态中成员方法的使用方法

  • 成员变量:编译看左边,运行看左边
    成员方法:编译看作左边,运行看右边
 public class Fu {
    public void methodFu(){
        System.out.println("父类方法");
    }

    public void method(){
        System.out.println("fu 10");
    }

}

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


public class Demo {
    public static void main(String[] args) {
        Fu obj = new Zi();
        obj.methodFu();  //父类方法//先看左边是Fu,先到Fu类找,有这个方法,再到右边Zi类运行,发现没有,向上找到Fu类,运行此方法

        obj.method();//20// 先看到左边是Fu,先到Fu类去找,有这个方法,再到右边Zi类运行,发现有这个方法,直接运行

        //obj.methodZi(); //看到左边是Fu,先到左边Fu类去找,没有这个方法,就不到右边子类去找了
    }
}

======================================================================================
多态的好处
员工(父类)work();//抽象方法
extends或者implements
zilei :讲师 work(jiangke); 助教 work(fudao);

不是用多态:
Teacher one = new teacher();
one.work();//讲课
Assistant two = new Assistent();
two.work();//辅导

多态:
Employee one = new Teacher();
one.work();
Employee two = new Assistant();
two.work();

好处:无论右边切换成哪个子类对象,等号左边调用方法都不变

对象向上转型
1.对象向上转型就是多态写法
格式: 父类名称 对象名 = new 子类名称();
含义:右侧创建一个子类对象,把它当做父类来看待

Animal animal = new cat();

注意:向上转型一定是安全的,从小范围转到了大范围.

================================================
对象向下转型 其实就是一个还原动作
问题:向上转型一定是正确的,但是也有一个弊端
对象一旦向上转型为父类那么无法调用子类原来特有的内容

解决方案:向下转型

格式:子类名称 对象名 = (子类名称)父类对象;
含义:将父类对象,【还原】成本来的子类对象
Animal animal = new Cat();//本来是猫,向上转型成动物
Cat cat = (Cat) animal;//本来是猫,向上转型成动物,还原回来成为本来的猫

注意事项:
1.必须保证对象本来创建的时候,是猫,才能向下转型成猫
2.如果对象创建的时候本来不是猫,现在非要向下转型为猫,就会报错

public abstract class Animal {            //父类定义成为抽象类,用abstract修饰
    public abstract void eat();           //父类中的抽象方法
}

public class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
    public void play(){
        System.out.println("猫抓老鼠");//猫特有的
    }
}

public class Gog extends Animal{
    public void eat(){
        System.out.println("狗吃SHIT");
    }
    public void play1(){
        System.out.println("gouzi");
    }
}


public class Demo {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();                    new的是猫类

        //animal.play();
        Cat cat = (Cat)animal;            //强制转
        cat.play();

        //Gog dog = (Gog) animal;         //编译不会报错,运行会报错,转错啦
        //dog.play1();

    }
}

=============================================
用instanceof关键字进行判断

public class Demo {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();

        //animal.play();//错误
		
        Cat cat = (Cat)animal;
        cat.play();

        if(animal instanceof Gog)     //返回一个真假值
        {
            Gog dog = (Gog)animal;
            dog.play1();
        }

        if(animal instanceof Cat)
        {
            Cat catt = (Cat)animal;
            catt.play();
        }

        //Gog dog = (Gog) animal;
        //dog.play1();

    }
}

===============

public class Demo {
    public static void main(String[] args) {
        Animal animal = new Cat();
        
	    giveanimal(new Cat());
	}
	
			
	public static void giveanimal(Animal animal){
	
           if(animal instanceof Gog)     //返回一个真假值
        {
            Gog dog = (Gog)animal;
            dog.play1();
        }

        if(animal instanceof Cat)
        {
            Cat catt = (Cat)animal;
            catt.play();
        }
}
}		
       

=================================================================

Usb
另一篇博客里有详细的讲解
在这里插入图片描述

public interface Usb {                //创建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 play(){                     //Mouse的特有方法
        System.out.println("点击鼠标");
    }
}


public class Key implements Usb{                     //接口的实现类
    @Override
    public void open() {                             //引用接口的抽象方法
        System.out.println("打开键盘");
    }

    @Override
    public void close() {                           //引用接口的抽象方法
        System.out.println("关闭键盘");
    }

    public void play1(){                           //Key实现类的特有方法
        System.out.println("键盘输入");
    }
}


public class Compute {
    public void open(){                     //类里的开机方法
        System.out.println("打开电脑");
    }
    public void close(){                    //类里的关机方法
        System.out.println("关闭电脑");
    }

    public void UseUsb(Usb usb){            //构造一个使用Usb接口的方法,并接收Usb类型的参数
        usb.open();                         //谁new的,看谁实现的接口

        if(usb instanceof Mouse){           //判断实现类是谁,实现对象的向下转型,并调用实现类中的特有方法
            Mouse mouse = (Mouse) usb;
            mouse.play();
        }

        if(usb instanceof Key){
            Key key = (Key) usb;
            key.play1();
        }
        usb.close();
    }
}

public class Demo {
    public static void main(String[] args) {
        Compute compute = new Compute();// new一个Compute对象

        compute.open();                 //电脑开机

        Usb usb = new Key();             //左边是接口,右边是实现类。 这也是多态。

        compute.UseUsb(usb);             //传递Usb类型的参数向compute类里的接收Usb的方法中
        compute.UseUsb(new Mouse());

        compute.close();
    }
}

=================================================================
final关键字
代表最终的、不可改变的
常见四种方法
1.可以用来修饰一个类
2.可以用来修饰一个方法
3.可以用来修饰一个局部变量
4.可以用来修饰一个成员变量

1.当前这个类不能有任何子类(太监类)
public final class 方法名称{
----
}
注意:一个类是final类,那么其中所有成员方法都无法进行覆盖重写

public final class MyClass{
      public void method(){
	       System.out.println("方法执行");
		   }
	}

2.不能被覆盖重写
父类中这个方法被final修饰后,这个方法在子类中不能被覆盖重写

注意:方法来说,abstract关键字和final关键字不能被同时使用

public class Fu {
    public final void meth(){
        System.out.println("final父类");
    }
    public void meth1(){
        System.out.println("无final父类");
    }
}


public class Zi extends Fu {

   /* public void meth(){       //错误写法
        System.out.println("测试");
    }
    */
    public void meth1(){
        System.out.println("覆盖");
    }
}

public class Demo {
    public static void main(String[] args) {
        Zi obj = new Zi();
        obj.meth1();
        obj.meth();
    }
}

==============================================
3.final修饰局部变量

public class Demo {
    public static void main(String[] args) {
        int num1=10;
        num1=20;
        System.out.println(num1);

        final int num2=20;
        /*num2=30;  错误,用final定义后,不能改变值*/

        //正确,只要赋值一次就可以
        final int num3;
        num3=30;

        //对于基本类型来说,不可变的的是变量当中的数据值
        //对于引用类型来说,不可改变的是变量当中的地制值

    Student stu = new Student("赵丽颖");
    System.out.println(stu);//打印的地址,一
         System.out.println(stu.getName());
    stu = new Student("霍建华");
    System.out.println(stu);//打印的地址,与一不同
        System.out.println(stu.getName());


    final Student stu1 = new Student("高圆圆");
    /*stu1=new Student("高圆圆圆圆");  错误,地址不能改变*/

        stu1.setName("高圆圆圆圆");//虽然地址不能改变,但是里面的值可以改变
    System.out.println(stu1.getName());
    }
}



public class Student {
    private  String  name;
    public Student(){

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

    public String getName() {
        return name;
    }

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

==========================================
final修饰成员变量
1.由于成员变量具有默认值,所以用了final之后必须手动赋值,就不会给默认值了
2.对于final成员变量,要么直接赋值,要么通过构造方法进行赋值。二者选其一
3.必须保证类中所有重载的构造方法,都最终会对final的成员变量进行赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值