Java语法之多态、抽象类、引用型的数据类型转换、Object类的使用

发布时间:2023-07-15 16:30

3.4 多态

多态 : 一种事物的多种形态|表现形式,是一种行为多态。

  • 多态前提 :
    • 继承 | 实现
  • 多态的最终表现形式 :
    • 父类引用指向子类对象
  • 多态的调用 : 父类引用调用
    • 成员变量 :编译运行看父类|左边|类型
    • 成员方法 :编译看父类|左边|类型,运行找子类|右边|对象
  • 注意:
    • 如果没有配合方法的重写,多态就没有意义。方法没有重写的话,就可以直接用对象直接调用不同名的方法。
public class Class001_Poly {
    public static void main(String[] args) {
        //对应类型数据赋值给对应类型的变量
        Person p = new Person();
        Student s = new Student();
        //正常调用 : p或者s调用的成员 : 1)自己类中存在的成员  2)从父类中继承的成员


        //多态
        Person  ps=  new Teacher();
        //多态的调用
        System.out.println(ps.str);

        ps.test();

    }
}

class Person{
    String str = "父类";

    public void test(){
        System.out.println("Person----> test");
    }
}

class Student extends Person{
    String str = "子类";

    public void test(){
        System.out.println("Student----> test");
    }
}

class Teacher extends Person{
    String str = "子类2";

    public void test(){
        System.out.println("Teacher----> test");
    }
}

3.4.1 数据类型转换

  • 基本 : 数据类型转换

    • 自动类型提升 : 小 —> 大
    • 强制类型转换 : 大 —> 小
      • 小范围类型 变量 = (小范围类型)大范围类型数据;
  • 引用 : 转型

    • 小: 子类 大 : 父类
    • 向上转型 : 子类 --> 父类
    • 向下转型 : 父类 --> 子类
      • 子类类型 变量 = (子类类型)父类引用;
      • 需求 : 当多态调用不能调用子类独有内容时候,可以向下转型,然后调用子类独有内容
  • java.lang.ClassCastException类型转换异常

    • 在向下转型的时候,如果抓成其他的子类类型,就会遇到这个异常
  • instanceof 运算符

    • 引用 instanceof 类型 : 判断前面的引用是否指向后面类型的对象或者后面类型的子类对象,如果是返回true,不是返回fales
public class Class001_Cast {
    public static void main(String[] args) {
        int i = 1;
        //自动类型提升
        long l = i;
        //强制类型转换
        int i2 = (int)l;

        Zi zi = new Zi();
        //向上转型
        Fu fu = zi;
        //多态
        Fu f = new Zi(); //f对子类新增内容不可见

        //向下转型
        //Zi zi2 = (Zi)f;  //Zi zi2 = new Zi();  --> 可以调用子类独有内容
        //转型转错了,转成了其他的子类类型---> java.lang.ClassCastException类型转换异常

        if(f instanceof Brother){
            Brother zi2 = (Brother)f;  //Brother zi2 = new Zi();  --> 可以调用子类独有内容
            zi2.test();
        }else if(f instanceof Zi){
            Zi zi2 = (Zi)f;
            zi2.test();
        }

        System.out.println(f instanceof Fu);  //T
        System.out.println(f instanceof Zi);  //T
        System.out.println(f instanceof Brother);  //F
    }
}
class Fu{}

class Zi extends Fu{
    String str="Zi";
    void test(){
        System.out.println("子类Zi方法test");
    }
}

class Brother extends Fu{
    String str="Brother";
    void test(){
        System.out.println("子类Brother方法test");
    }
}

3.4.2 Object类

  • Object : 老祖宗类

    • 是java中所有类的父类
    • 如果一个类没有显示的继承父类,默认继承自Object类
  • toString :返回对象的字符串表现形式

    • public String toString() {
      return getClass().getName() + “@” + Integer.toHexString(hashCode());
      }
      当输出一个对象 的引用的时候,输出的是对象的引用调用toString方法的返回值==>默认调用toString
    • 为什么要在子类中重写toString方法 :
      • 因为输出对应的引用时候不想是打印对象的地址值,想要输出对象的所有属性值,对从Object中继承的toString需要,toString实现不满意,在子类中重写toString
    • 注意:当定义javabean类型,规范都需要重写toString
  • ==:比较两个数据是否相等

    • 基本 : 数据值
    • 引用 : 对象地址值
  • equals:比较两个对象数据是否相等

    • Object类中的equals方法 : 默认比较对象的地址值
      public boolean equals(Object obj) {
      return (this == obj);
      }
  • 为什么要子类中重写equals方法 :

    • 使用Object类的equals方法,默认比较对象地址,业务需求想要比较根据对象的属性值比较是否相等,可以在子类中根据需要重写equals,实现比较对象所有属性而非地址值
  • 注意:javabean的定义规范 :

    1. 类是公共的
    2. 至少提供一个空构造
    3. 属性私有化
    4. 公共的访问方式
    5. 重写equals与toString方法
public class Class001_Object{
    public static void main(String[] args) {
        Student s1 = new Student(1001,"张三丰",100);
        Student s2 = new Student(1001,"张三丰",10);
        System.out.println(s1);
        System.out.println(s1.toString());

        System.out.println(s1.equals(""));;
    }
}

class  Student{
    int no;
    String name;
    int age;

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

    public String toString() {
        return no+"-->"+name+"-->"+age;
    }

    //比较字符串类型的数据 : 使用String重写的equals比较字符串对象的内容而非地址
    public boolean equals(Object obj) { //Object obj = new Student(1001,"张三丰",100);
        //增强程序健壮性判断
        if(this==obj){
            return true;
        }
        //两个对象 : this  obj
        //obj向下转型
        if(obj instanceof Student){
            Student s = (Student)obj;
            //两个对象 : this  s
            return this.no==s.no && this.age==s.age && this.name.equals(s.name);
        }
       return false;
    }
}

3.4.3 抽象类

  • 抽象类 : 被abstract修饰的类

  • 抽象方法 :被abstract修饰的方法

    • 没有方法体
    • 必须存在与抽象类中
  • 需求 :定义开发部门不同职位工作内容

    • 开发部门 Develop --> work()
    • java攻城狮 : work–> 后端开发
    • web程序猿 : work–> 前端开发
  • 注意 :

  1. 抽象类不能实例化
  2. 抽象方法必须存在与抽象类中
  3. 抽象类中可以定义可以不定义抽象方法,可以定义任意内容
  4. 抽象类的使用 :
    1. 具体子类对象调用成员
      重写所有的抽象方法 + 按需新增
    2. 抽象子类
      按需重写 + 按需新增
  5. 抽象方法必须被重写的,但是只需要重写一次,按需重写多次
  6. abstract不能与private,final,static,native一起使用
public class Class001_Abstract {
    public static void main(String[] args) {
        //抽象类不能实例化
        //Develop d = new Develop();

        //具体子类对象
        Java java = new Java();
        java.sleep();
        java.work();
        java.test();
        java.insert();
    }
}

//父类
abstract class Develop{
    //work方法体不知道怎么写,不知道写什么--->
    public abstract void work();
    public abstract void sleep();

    public void test(){
        System.out.println("抽象方法的test");
    }
}

//具体子类
class Java extends Develop{

    @Override
    public void work() {
        System.out.println("后端开发");
    }

    @Override
    public void sleep() {
        System.out.println("边敲代码边睡觉... ");
    }

    //新增
    public void insert(){
        System.out.println("java中新增方法");
    }
}

//抽象子类
abstract class Web extends Develop{

    @Override
    public void work() {
        System.out.println("前端开发");
    }

    //新增
    public void webInsert(){
        System.out.println("web 新增");
    }
}

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号