多态的理解与使用

多态

调用多态的方法如下,同一个行为表现出不同的行为特征

多态的常见形式

父类类型 对象名称 = new 子类构造器

接口 对象名称 = new 实现类构造器

 使用方法1:

public class Animal{
    public void run(){
        //输入内容
    }
}

//狗继承方法重新
public class Dog extends Animal{
    public String name="变量名称1"
    @Override
    public void run(){
        //重新内容
    }
}

//乌龟继承方法重新
public class Tortoise extends Animal{
    public String name="变量名称2"
    @Override
    public void run(){
        //重新内容
    }
}

public class Test {
    public static void main(String[] args) {
        //目标:先认识多态形式
        //父类:对象名称= new 子类构造器();
        Animal a = new Dog();
        a.run();
        a.name//变量名称1

        Animal a1=new Tortoise();
        a1.run();
        a1.name//变量名称2
    }
}

 使用方法2

public class Test {
    public static void main(String[] args){
        Animal d=new Dog();
        go(d);
        d.Animal里面的方法;//可以
        d.Dog里面的方法;//报错
    }


    public static void go(Animal a){
        System.out.println("第一步")
        a.run(); //第二步
        System.out.println("第三步")
    }
}

多态中成员访问特点

  • 方法调用:编译看左边,运行看右边
  • 变量调用:编译看左边,运行也看左边。(多态侧重行为多态)

多态前提

有继承/实现关系;有父类引用指向子类对象;有方法重写

多态的优势

  • 多态形式下,右边对象可以实现解耦合,便于扩展和维护

Animal a = new Dog();

a.run(); // 后续业务行为随对象而变,后续代码无需修改

  • 定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。

多态的劣势

  • 多态下不能使用子类的独有功能

多态的类型转换 

自动类型转换(子到父):之而立对象赋值给父类类型的变量指向

强制类型转换(父到子):

  • 此时必须进行强制类型转换:子类 对象变量=(子类)父类类型的变量
  • 作用:可以解决多态下的劣势,可以实现调用子类独有 的功能
  • 注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException
Animal t = new Tortoise();
Dog d=(Dog)t; // 出现异常 ClassCastException

java建议强制装换前使用instanceof判断当前对象的真实类型,再进行强制转换

变量名  instanceof 真实类型

判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之返回false

多态的综合案例

有参数构造器的创建

 

//创建一个接口
public interface USB {
    //接入
    void connect();
    //拔出
    void unconnect();
}

//创建一个鼠标实现接口
public class Mouse implements USB{
    private String name;

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

    @Override
    public void connect() {
        System.out.println(name+"成功接入设备");
    }

    @Override
    public void unconnect() {
        System.out.println(name+"成功弹出设备");

    }

    /**
     独有功能
     */
    public void click(){
        System.out.println(name+"双击点亮小黄车");
    }

    public String getName() {
        return name;
    }

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


//创建一个键盘实现接口
public class KeyBoard implements USB{
    private String name;

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

    @Override
    public void connect() {
        System.out.println(name+"成功接入设备");
    }

    @Override
    public void unconnect() {
        System.out.println(name+"成功弹出设备");

    }

    /**
     独有功能
     */
    public void keyDown(){
        System.out.println(name+"写下了评论,评论了666666");
    }

    public String getName() {
        return name;
    }

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


//创建一个电脑
public class Computer {
    /**
     提供一个安装入口:用一个行为代表
     */
    public void install(USB usb){
        usb.connect();

        //独有功能 判断真实类型并强转
        if(usb instanceof Mouse){
            Mouse m = (Mouse)usb;
            m.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard m=(KeyBoard)usb;
            m.keyDown();
        }

        usb.unconnect();
    }
}
//创建一个电脑
public class Computer {
    /**
     提供一个安装入口:用一个行为代表
     */
    public void install(USB usb){
        usb.connect();

        //独有功能
        if(usb instanceof Mouse){
            Mouse m = (Mouse)usb;
            m.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard m=(KeyBoard)usb;
            m.keyDown();
        }

        usb.unconnect();
    }
}

//创建一个方法接入鼠标和键盘
/**
    目标:USB设备模拟
    1.定义USB接口:接入  拔出
    2.定义一个USB实现类:鼠标、键盘
    3.创建一个电脑对象,再创建一个鼠标对象,模拟运行
 */
public class Test {
    public static void main(String[] args) {
        //创建定安路对象
        Computer c= new Computer();
        //创建USB设备对象
        USB usb =new Mouse("罗杰鼠标");
        c.install(usb);
    }
}

内部类

public class People{
    //内部类
    public class Heart{
    }
}

//运行方式
//外部类名.内部类名  对象 = new  外部类名.内部类名
People.Heart  p=new People.Heart
  • 当一个事物的内部,还有一个部分需要一个完整的解构进行描述,而这个内部的完整解构又只为外部事物提供服务,那么整个内部的完整结构可以使用内部类来设计。
  • 内部类通常可以方便访问外部类的成员,包括私有成员。
  • 内部类提供了更好的封装性,内部类本身就可以使用private protected等修饰,封装性可以做更多控制。

 静态类的使用场景、特点、访问总结

  • 如果一个类中包含了一个完整的成分,如汽车类中的发动机类
  • 特点、使用与普通类是一样的,类有的成分它都有,只是位置在别人里面而已
  • 可以直接访问外部类的静态成员,不能直接访问外部类的实例成员。
  • 注意:开发实际上用的还是比较少的。

 成员内部类创建对象的格式

格式:外部类名.内部类名  对象名 = new  外部内构造器.new  内部类构造器

范例:Outer.Inner  in = new Outer().new  Inner();

 匿名内部类

  • 本质上是一个没有名字的局部内部类,定义在方法中、代码块中、等。
  • 作用:方便创建子类对象,最终目的为了简化代码编写

格式: new 类 | 抽象类名 | 或者接口名(){ 重写方法 };

特点:

  • 匿名内部类是一个没有名字的内部类。
  • 匿名内部类写出来就会产生一个匿名内部类的对象。
  • 匿名内部类的对象类型相当于是当前new的那个类型的子类类型。 

案例

//为按钮绑定点击事件监听器
btn.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e){
        System.out.println("登录一下~~")
    }
})
//btn.addActionListener(e->System.out.println("登录一下~~"))


//模拟点击登录
public class btn {
    public static void main(String[] args) {
        JFrame win = new JFrame();
        JPanel Panel= new JPanel();
        win.add(Panel);
        JButton btn=new JButton("登录");
        Panel.add(btn);
        win.setLocationRelativeTo(null);
        win.setSize(300,200);
        win.setVisible(true);
        btn.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(win,"弹出提示框");
            }
        });

    }
}

常用API

Object

toString方法 

输出地址      // @Override...重写方法

equals方法:

比较地址返回true或false   s1.equals(s2)  默认比较地址是否相同  //@Override 重写

使用方法二:Objects.equals(s1,s2)

isNull方法

isNull(s1)  判断s1是否为null

StringBuilder  增加拼接效率

StringBuilder是一个可变字符串类,我们可以吧它看成一个对象容器

作用:提高字符串的操作效率,如拼接、修改等。

方法名称说明
public StringBuilder append(任何类型)添加数据并返回StringBuilder对象本身
public StringBuilder reverse()将对象的内容反转
public int length()返回对象内容长度
public String toString()通过toString()j就可以实现吧StringBuilder转换为String

使用方法

Math

方法名说明
public static int abs(int a)获取绝对值
public static double ceil(double  a)向上取整
public static double floor(double a)向下取整
public static int round (float  a)四舍五入
public static int max(int a,int b)获取两个int值中的较大值
public static double pow(double a,double b)返回a的b次幂的值
public static double random()返回值为double的随机值,范围【0.0,1.0)

System

方法名说明
public static void exit(int status)终止当前运行的java虚拟机,非零表示异常终止
public static long currentTimeMillis()返回当前系统的时间毫秒值形式                        从1970-1-1 00:00:00  算起
 public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数)数组拷贝

BigDecimal   用于解决浮点型运算精准度失真的问题

1.public static BigDecimal valueOf(double  val)  //将浮点类型包装成BigDecimal对象

方法名说明
public BigDecimal add(BigDecimal b)加法

public BigDecimal subtract(BigDecimal  b)

减法
public BigDecimal multiply(BigDecimal  b)乘法
public BigDecimal  divide(BigDecimal  b)除法
public BigDecimal divide(另一个BigDecimal 对象,精确几位,舍入模式)除法

推荐使用BigDecimal val =BigDecimal.valueOf(数字)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值