• JAVA笔记整理-面对对象-抽象、接口、多态


    一、抽象类

    1、定义

    ​ 在已有类的基础上,由于特殊情况将该类设置为抽象的,这个类就是抽象类

    语法:

    public abstract class 类{
          // 类的元素
    }
    

    什么情况下需要定义抽象类?

    1、当这个类不需要创建具体的实例时,可将类定义为抽象的

    2、当这个类中存在没有实现的方式时(没有方法体的方法),可以将这个类定义抽象的

    2、抽象类的特点

    ​ 2.1 抽象类 不能实例化(不能new) ,通常抽象被当作父类使用

    2.2 抽象类中 可以有抽象方法( 没有方法体的方法) 也可以有普通方法

    2.3 抽象类被当作父类时,它的子类必须重写父类的抽象方法

    public abstract class Fruit {
        private String color;
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        // 水果的甜度  由于不知道是什么水果,所以说过的甜度未知,可以定义为抽象方法
        // 抽象方法
        public abstract void getSweet();
    
    }
    
    
    public  class Apple extends  Fruit {
    
        // 子类重写(实现)父类的抽象方法
        @Override
        public void getSweet() {
            System.out.println("这个水果有点甜");
        }
    }
    
    
    public class Lemon extends  Fruit {
    
        @Override
        public void getSweet() {
            System.out.println("这个水果有点酸,想想都觉得酸");
        }
    }
    
    public static void main(String[] args) {
            // 抽象类不能实例化
          //  Fruit fruit = new Fruit();
            // 创建子类对象
            Apple apple = new Apple();
            apple.setColor("红色");
            apple.getSweet();
            System.out.println(apple.getColor());
    
            Lemon lemon = new Lemon();
            lemon.setColor("黄色");
            lemon.getSweet();
            System.out.println(lemon.getColor());
    
    
        }
    }
    

    面试题:抽象方法和非抽象方法的区别

    回答: 抽象方法没有方法体,需要使用abstract修饰, 只能写在抽象类中

    ​ 非抽象方法就是普通方法(成员方法或静态方法) ,可以写在抽象类中或普通类中。

    二、接口

    1、定义

    ​ 接口用于对某件事物的功能的声明,而没有实现具体功能 ,接口提供对软件开发的标准规范。

    ​ 利用接口的“多实现”完成Java的单一继承

    2、接口语法

    public interface 接口名{
          抽象方法定义
    }
    

    ​ 一个类实现该接口,必须实现接口的所有方法

    public class 实现类名  implements 接口名{
         实现接口的所有方法
    }
    

    接口的好处:

    1、为了规范实现类的行为,让所有的方法都通过接口定义

    2、为了提高代码的可扩展性

    接口定义实现类的对象 和 实现类定义试下类的对象的区别?

    接口定义实现类的对象只能调用接口中定义的方法, 实现类定义的对象既可以调用实现类的方法,也可以调用接口类的方法。

    3、接口中的成员组成部分 特点

    接口中定义的变量默认全部是 public static final 修饰的

    接口中的静态方法可以直接调用。

    接口中不能写构造器(因为接口不能实例化,不需要构造器)

    接口中的方法全部都是 抽象方法, 在JDK8以后可以定义default的非抽象方法

    案例1 : 一个类既可以继承一个类 也可以实现多个接口

    //定义一个门类 ,定义一个防盗门,它具有防盗的功能,如何防盗 (防盗功能中可以 拍照, 密码锁)
    // 门本 身有 开门,关门 功能
    public interface Security {
        String  password="666";
        //功能方法
        
        //拍照
        public void picture();
    
        //判断密码方法
        public boolean ifpass(String password);
    }
    public class SecurityDoor extends Door implements Security {
        String color;
        String password2;
        public SecurityDoor(String doorClass,String color,String password2){
            super( doorClass);
            this.color=color;
            this.password2=password2;
        }
        //拍照
        public void picture(){
            System.out.println("已拍照");
        }
        //判断密码
        public boolean ifpass(String password2){
            // equals比较两个字符串的值是否相等
            if(password.equals(Security.password)){
                return true;
            }
            return false;
        }
        //开门
        public void putdoor(){
            System.out.println("已开门!");
        }
        //关门
        public void outdoor(){
            System.out.println("已关门!");
        }
        //输出信息
        public void message(){
            System.out.println("门类型:"+doorClass);
            System.out.println("颜色:"+color);
        }
    }
    //测试
    public class Text_SecurityDoor {
        public static void main(String[] args) {
            SecurityDoor door1=new SecurityDoor("普通门","棕色");
            SecurityDoor door2=new SecurityDoor("防盗门","浅黄色");
          //输出门所有信息
            door1.message();
            door1.putdoor();
            door1.outdoor();
    
    
            door2.message();
            door2.picture();
           if(door2.ifpass(door2.psd)==true) {
               System.out.println("密码正确!");
               door2.putdoor();
           }else {
               System.out.println("密码错误");
           }
               door2.outdoor();
        }
    }
    
    
    

    结果:

    门类型:普通门
    颜色:棕色
    已开门!
    已关门!
    门类型:防盗门
    颜色:浅黄色
    已拍照
    密码正确!
    已开门!
    已关门!:

    案例2: 一个类可以实现多个接口,中间用逗号分隔 (那么这个类要实现接口的所有方法)
    /**
     *  程序员身份
     */
    public interface Programer {
        public void takeMoney();
    }
    /**
     * 厨师
     */
    public interface Cooker {
        /**
         * 做好吃
         */
        public void makeFood();
    }
    public interface Driver {
        // 功能
        public void driverCar();
    
        public void takeMoney();
    }
    
    
    public class People implements Programer ,Cooker ,Driver {
    
        private String name;
        public People (String name){
            this.name = name;
        }
        @Override
        public void makeFood() {
            System.out.println("做好吃的");
        }
    
        @Override
        public void driverCar() {
            System.out.println("开车的功能");
        }
    
        @Override
        public void takeMoney() {
            System.out.println("赚钱的功能");
        }
    }
    
    
     public static void main(String[] args) {
             People people = new People("张三");
             people.takeMoney();
             people.makeFood();
             people.driverCar();
        }
    

    案例3:一个接口可以继承 接口,或多个接口(接口可以多继承)

    一个员工接口 一个程序员 (由于程序员是员工,所有程序员可以继承员工接口 )

    一个人 是员工也是 程序员 (People 是员工 程序员 )

    三、多态

    多态:继Java面向对象中封装,继承之后的第三个特征

    生活中的多态: 同一个行为,例如跑,人是两条腿跑,动物是四条腿或两条腿跑,飞的行为不同是事物飞的方式也不同,飞机飞,小鸟飞,无人机飞都不一样,同一种行为对于不同的事物呈现的不同形态就是多态的表现。

    1、 定义

    ​ 同一种行为,具有多个不同的表现形式

    2、实现多态的前提

    • 基于继承关系或基于实现关系的
    • 子类或实现类必须对方法进行重写(没有重写的方法 不具有多态行为)
    • 父类的引用指向子类对象( 接口的引用指向实现类的对象)

    3、多态的对象转型

    1、子类对象转父类对象时,称为向上转型是默认转换,自动转型

              Cat cat = new Cat();
               // 猫类 可以是一只动物 an4的本质还是 创建的猫对象
              Animal an4 = cat;    // 子类对象转成父类对象 ,是自动转型
               cat.eat();   
               an4.eat();
    

    2、父类的引用转成子类对象,称为向下转型,向下转型需要强转 , 为了避免转换错误,需要先判断数据类型是否匹配

       // 创建一个动物类, 将动物类转成子类引用
               Animal an5 = new Cat();
              //  an5.catchMouse(); // 动物类型对象不能访问 它子类特有的方法
              if(an5 instanceof Cat) {
                  Cat cat2 = (Cat) an5;
                  cat2.eat();
                  cat2.catchMouse();
              }
              if(an5 instanceof  Dog) {
                  Dog dog2 = (Dog)an5;
              }else{
                  System.out.println("不能转成dog");
              }
    

    instanceof : 判断该对象是否属于 这个类型

    ​ 为什么需要做类型换行呢? 有时候我们需要调用子类特用的方法时必须用子类的引用。所有多态对象下父类应用需要强转。

    为了避免ClassCastException(类型强制转换异常)的发生,Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:

    变量名 instanceof 数据类型如果变量属于该数据类型,返回true。
    
    如果变量不属于该数据类型,返回false
    

    4、在多态环境型,方法和属性的调用规则

    属性: 当子类和父类中存在相同属性时 ,以 对象的左边引用类型为依据,所谓“看左边”

    方法: 以当前new出来的对象为依据,如果方法重写了,就调用子类方法,如果方法没有重写 调用父类方法

    静态方法: 无论方法是否有重写, 都已对象左边的引用类型为依据。

    
    
    public class Student extends  People  {
          int age =20;
    
        @Override
        public void showAge() {
            this.age++;
            System.out.println("年龄:"+this.age+" ----"+super.age);
    
        }
        // 重写的静态方法
        public static void  method1(){
            System.out.println("method1------------  重写后的 方法");
        }
    
    }
    
    public static void main(String[] args) {
          People p1 = new People();
          System.out.println(p1.age);// 18
           p1.showAge();  // 对象的本质people  调用people
    
           People p2 = new Student();
          System.out.println( p2.age);// 18
          p2.showAge(); // 本质student ,且重写了 调Student
          p2.sleep();  // 本质student  ,没重写,调用people
    
            Student p3 = (Student)p2;
         System.out.println( p3.age); // 20
            p3.showAge(); // 本质student ,且重写了 调Student
    
            People p4 = p3;
         System.out.println( p4.age); // 18   看左边
            p4.showAge(); // 本质student ,且重写了 调Student
    
    }
    

    结论:

    18
    年龄:18
    18
    年龄:21 ----18
    睡觉方法。。。。。
    21
    年龄:22 ----18
    18
    年龄:23 ----18

    public static void main(String[] args) {
          People p1 = new People();
          p1.method1();
          p1.method2();
    
          People p2 = new Student();
          p2.method1();
          p2.method2();
    
          Student p3 = (Student)p2;
          p3.method1();
          p3.method2();
    
    }
    

    结论:

    method1------------
    method2---------
    method1------------
    method2---------
    method1------------ 重写后的 方法
    method2---------

    总结常见面试题:

    ## 1、抽象类与接口的区别

    ​ 共同点: 它们都是抽象的,都不能实例化

    区别:

    ​ 1、抽象类是类 使用abstract修饰,接口使用interface定义

    ​ 2、抽象类中可以包含抽象方法和普通方法, 接口中是纯粹的抽象类,都是抽象方法,除使用default定义以外

    ​ 3、子类继承抽象类,必须实现抽象类的方法,或者自身变为抽象类

    ​ 接口中是实现关系,实现类必须实现接口的所有方法,接口中定义的值是默认为:public static final

    2、重载和重写的区别?

    1、重写存在于父子关系中的不同类,重载存在同一个类中

    2、重写必须满足 方法名相同,且参数相同,返回值相同 ,重载满足方法名相同,参数不同,与返回值无关。

    3、重写的访问修饰符必须 子类大于等于父类, 重载没有要求

    3、在java中如何实现多态(多态的前提条件)?

    • 基于继承关系或基于实现关系的
    • 子类或实现类必须对方法进行重写(没有重写的方法 不具有多态行为)
    • 父类的引用指向子类对象( 接口的引用指向实现类的对象)

    4、final的作用

    ​ final修饰变量 定义为常量

    ​ final 修饰方法 不能被重写

    ​ final 修饰类 则不能被其他子类继承

  • 相关阅读:
    Spring系列之访问数据库
    (转载)Java反射机制
    Spring系列之IOC容器
    SpringMVC系列之基本配置
    Java中Comparable和Comparator区别小结
    计算机网络知识点回顾
    Java内部类
    Java接口回调机制
    linux mysql-bin.000001占用磁盘空间过大解决方法
    linux mysql数据库登录密码忘记了怎么办
  • 原文地址:https://www.cnblogs.com/z5452830/p/13798460.html
Copyright © 2020-2023  润新知