黑马程序员Java基础7

------------java基础d7--01---final关键字-详解-Java常量---------------------------------------------------------

面向对象高级:final、单例类、枚举类、抽象类、接口

final:最终。可以修饰类、方法、变量。

大概的作用:

  1. 修饰类:该类被称为最终类,特点是不能被继承了。
  2. 修饰方法:该方法被称为最终方法,特点是不能被重写了。
  3. 修饰变量:该变量有且仅能被赋值一次。
java 复制代码
package com.itheima.finaldemo;

public class FinalDemo1 {
    public static void main(String[] args) {
        //目标:认识final关键字的作用

    }
}
//一、final修饰类
final class A{
//比如工具类可以加final、反正工具类就是方便调用功能,又不需要改什么信息。
}

//class B extends A{
// 会报错,因为A类被final修饰了,不能被继承。
//}
//二、final修饰方法
class C{
    public final void show(){
        System.out.println("show方法执行了");
    }
}

class D extends C{
//    @Override
//    public void show() {  //会报错,因为父类方法被final修饰了,不能被重写
//        System.out.println("子类方法执行了");
//    }
}
//三、final修饰变量:成员变量(静态成员变量和实例成员变量)、局部变量。
class E{
    //1、final修饰静态成员变量
        //修饰静态变量,这个静态变量今后被称为常量,可以记住一个固定值,并且程序中不能修改了,通常这个值昨晚系统的配置信息。
            //常量的名称,建议全部大写,多个单词用下划线链接。
    public static final int a = 3;//一般把final放到static后边。 static在内存中只加载一次。
    public final static int b = 3;//语法上没问题。
//    a = 3;//会报错,因为a被final修饰了,不能被修改。
    //2、final修饰实例成员变量
        //修饰实例变量,一般没有意义。不能所有对象的名字都叫猪刚鬣
    private final String name = "猪刚鬣";

    //3、final修饰局部变量
    public static void bug(final double  c){
        //如此,输入的c值就不能被修改。相当于给他保护起来了。
    }

}

注意:

  1. final修饰基本类型的变量,变量存储的数据不能被改变。
  2. final修饰引用类型的变量,变量储存的地址不能被改变,但地址所指向的内容是可以被改变的。

常量的使用:

  1. 使用了static final修饰的成员变量就被称为常量。

    1. 作用:常用于记录系统的配置信息。
    java 复制代码
    public class Constant{
        public static final String SCHOOL_NAME = "传智教育";
    }

    常量的名称全用大写字母,单词之间用下划线链接。
    3. 企业开发时,会单独搞一个Constant包,专门用来存放常量。

  2. 使用常量记录系统配置信息的优势、执行原理:

    1. 代码可读性更好,可维护性也更好。

    2. 疑问:开发中用常量,会不会导致性能不好?还要寻址,找包找变量的?

      1. 对性能没有影响,程序编译后,常量会被宏替换:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接字面量的性能是一样的。

      java 复制代码
      package com.itheima.finaldemo;
      
      public class Constant {
          //常量包。
          public static final String SYSTEM_NAME = "传智播客";
      }
      java 复制代码
      package com.itheima.finaldemo;
      
      public class FinalDemo2 {
          public static void main(String[] args) {
              //目标:了解final修饰成员变量为常量。
              System.out.println(Constant.SYSTEM_NAME);
              System.out.println(Constant.SYSTEM_NAME);
              System.out.println(Constant.SYSTEM_NAME);
              System.out.println(Constant.SYSTEM_NAME);
              System.out.println(Constant.SYSTEM_NAME);
              System.out.println(Constant.SYSTEM_NAME);
          }
      }

------------java基础d7--02---单例设计模式-懒汉式单例-饿汉式单例------------------------------------------

什么是设计模式?

  1. 一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式
  2. 设计模式有20多种,对应20多种软件开发中会遇到的问题。
  3. 关于设计模式主要学什么?
    1. 解决什么问题?
    2. 怎么写?

单例设计模式:

  1. 作用:确保某个类只能创建一个对象。
    1. 比如电脑的任务管理器,只有一个,不管启动多少次,只能有一个。
  2. 写法?实现步骤?
    1. 把类的构造器私有。
    2. 定义一个类变量记住类的一个对象。
    3. 定义一个类方法,返回对象。
  3. 单例类有很多种形式,比如
    1. 饿汉式单例:拿对象时,对象早就创建好了:
      1.

      java 复制代码
      package com.itheima.singleinstance;
      
      public class A {
          //饿汉式:设计成单例类
          //2、定义一个静态变量,用于记住本类的唯一对象。
          public static A a = new A();
          public static int a2 = 20;//语法上等同于上边的代码。
          private A(){}//1、首先,私有化构造器,确保外界不能随便创建对象。
          //但是以上,不专业。能让人家给弄丢了。
          //解决方案1:用final修饰。
      //    public static A a = new A();
          //解决方案2:私有化静态变量,然后提供一个公开的静态方法,返回这个类的唯一对象。
      //    private static A a = new A();
      //    public static A getInstance(){
      //        return a;
      //    }
      }

      阿巴

    2. 懒汉式单例:拿对象时,才开始创建对象。

      1. 实现步骤:

        1. 把类的构造器私有;

        2. 定义一个静态比哪里用于存储对象,

        3. 提供一个静态方法,保证返回的是同一个对象。

      2. 代码:

        java 复制代码
        package com.itheima.singleinstance;
        
        public class B {
            //2、定义一个类变量用于存储对象
            private static B b;
            //1、私有化构造器,确保外界不能创建对象。
            private B(){}
            
            //3、定义一个静态方法,返回本类的对象。
            public static B getInstance(){
                if (b == null){
                    b = new B();
                }
                return b;
            }
        }

小结:

  1. 什么是设计模式,设计模式主要学什么?单例模式解决了什么问题?
    1. 具体问题的最优解决方案。
    2. 解决了什么问题?怎么写?
    3. 确保某个类只能创建一个对象。
  2. 单例怎么写?饿汉式单例的特点是什么?
    1. 把类的构造器私有,定义一个静态变量存储类的一个对象,提供一个静态对象返回对象。
    2. 在获取类的对象时,对象已经创建好了。
  3. 单例有啥应用场景?有啥好处?
    1. 任务管理器对象、获取运行时对象。
    2. 在这些业务场景下,使用单例模式,可以避免浪费内存。
  4. 懒汉单例模式的特点是什么?
    1. 要用类的对象时才创建对象(延迟加载对象)
  5. 兰花单例模式怎么写?
    1. 把构造器私有
    2. 定义一个类变量用于存储对象。
    3. 提供一个类方法,保证返回的是同一个对象。

------------java基础d7--03---枚举-认识枚举---------------------------------------------------------------------------

  1. 枚举类是一种特殊类。

  2. 格式

    1. 修饰符 enum 枚举类名{

      名称1,名称2,名称3......;

      其他成员......}

  3. 特点:

    1. 枚举类的第一行,只能写枚举类的对象名称,且要用逗号隔开。

    2. 这些名称,本质是常量,每个常量都记住了枚举类的一个对象。

    3. 枚举类是一种最终类,不可以被继承,并且每个枚举类都是继承java.lang.Enum类的。

      复制代码
      public enum A{
          X, Y, Z;
      }
      //相当于
      public final class A extends java.lang.Enum<A>{
          public static final A X = new A();
          public static final A Y = new A();
          public static final A Z = new A();
      
          public static A[] values();
          public static AvalueOf(java.lang.String);
      }

      (这是一个多例类,如果只写一个X就是一个单例类)

    4. 枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。

    5. 编译器为枚举类新增了几个方法。

      1. 枚举类重写了toString方法。

      复制代码
      A a1 = A.X;
      System.out.println(a1);//X
      A a2 = A.Y;
      System.out.println(a2);//Y
      System.out.println(a1.name());//X
      System.out.println(a1.ordinal());//1
      System.out.println(a2.ordinal());//2

------------java基础d7--04---枚举-应用场景---------------------------------------------------------------------------

  1. 常见应用场景:
    1. 适合做信息分类和标志。
      1. 比如,做数字华容道的时候,用来接收上下左右四个方向的时候,可以用枚举。
java 复制代码
package com.itheima.enumdemo;

public class Constant {
    public static final int UP = 8;
    public static final int DOWN = 2;
    public static final int LEFT = 4;
    public static final int RIGHT = 6;
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.enumdemo;

public enum Direction {
    UP, DOWN, LEFT, RIGHT;
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.enumdemo;

public class Test2 {
    public static void main(String[] args) {
        //目标:掌握枚举类的应用场景,做信息的分类和标志
        //需求,模拟上下左右移动图片
        //两种方法做,1、用常量做西悉尼标志和分类。2、用枚举做分类和标志。
        //1、用常量做西悉尼标志和分类。   局限性:参数值不受约束。
        move(Constant.RIGHT);
        move(123456);//输入不受约束,输入什么都可以。
        //2、用枚举做分类和标志。
        move(Direction.UP);
//        move(UP);//输入受约束,输入什么只能是枚举的参数值。
    }
    //方法1:
    public static void move(int direction){
        //根据这个方向做移动,上下左右;
        switch (direction){
            case Constant.UP:
                System.out.println("向上移动");
                break;
            case Constant.DOWN:
                System.out.println("向下移动");
                break;
            case Constant.LEFT:
                System.out.println("向左移动");
                break;
            case Constant.RIGHT:
                System.out.println("向右移动");
                break;
        }
    }
    //方法2:
    public static void move(Direction direction){
        switch (direction){
            case direction.UP://这里的direction都可以省略,只写UP。
                System.out.println("向上移动");
                break;
            case direction.DOWN:
                System.out.println("向下移动");
                break;
            case direction.LEFT:
                System.out.println("向左移动");
                break;
            case direction.RIGHT:
                System.out.println("向右移动");
                break;
        }
    }
}

switch本身就支持去枚举里面找值。direction可以省略就能看出来。

------------java基础d7--05---抽象类-认识抽象类---------------------------------------------------------------------

抽象类:abstract;;

  1. abstract意思是抽象,可以修饰类、成员方法。

    1. 修饰类,就是抽象类;
    2. 修饰方法,就是抽象方法。
  2. 格式:

    1. 修饰符 abstract class 类名{

      修饰符 abstract 返回值类型 方法名称(形参列表);

      }

      java 复制代码
      public abstract class A{
          //抽象方法:必须abstract修饰,只有方法前面,不能有方法体。
          public abstract void test();
      }
  3. 注意事项、特点:

    1. 抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类

    2. 类的成员:成员变量、方法、构造器、抽象类都可以有。

    3. 抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。

    4. 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义为抽象类。(抽象类的使命就是被继承)

小结:

  1. 抽象类、抽象方法是什么样的?
    1. 都是用abstract修饰的,抽象方法只有方法签名,不能写方法体。
  2. 抽象类有哪些注意事项和特点?
    1. 抽象类中可以不写抽象方法,但有抽象方法的类必须是抽象类。
    2. 类的成员(成员变量、方法、构造器)抽象类都具备。
    3. 抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
    4. 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。

------------java基础d7--06---抽象类-好处、应用场景---------------------------------------------------------------

抽象类的好处:

  1. 父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,
    1. 设计这样的抽象类,就是为了更好的支持多态。
    2. 最佳实践,写抽象类比写普通类的父类更优雅。
java 复制代码
//抽象类父类------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract2;

public abstract class Animal {
    //描述每个动物的叫声。
    public abstract void cry();


}

//抽象类子类猫------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract2;

public class Cat extends  Animal{
    @Override
    public void cry() {
        System.out.println("猫是喵喵喵的叫");
    }
}

//抽象类子类狗------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract2;

public class Dog extends  Animal{
    @Override
    public void cry() {
        System.out.println("狗是汪汪叫");
    }
}
java 复制代码
package com.itheima.abstract2;

public class Test {
    public static void main(String[] args) {
        //目标:搞清楚使用抽象类的好处、
        Animal a = new Dog();
        a.cry();//因为抽象类一定要重写父类的抽象方法,所以这里不容易拉下,更好的支持多态。
    }
}

------------java基础d7--07---抽象类-模板方法设计模式------------------------------------------------------------

  1. 模板方法设计模式:
    1. 提供一个方法作为完成某类功能的模板,模板方法封装了每个实现步骤,但运行子类提供特定步骤的实现。
    2. 模板方法设计模式可以:
      1. 提供代码的复用、
      2. 并简化子类设计。
  2. 写法:
    1. 定义一个抽象类
    2. 在里面定义两个方法:
      1. 一个是模板方法:把相同的实现步骤放到里面去;
      2. 一个是抽象方法:不确定的实现步骤,交给具体的子类案来完成。
  3. 多学一找:建议使用final关键字修饰模板方法。
    1. 因为模板方法就是给子类直接使用的,不建议被子类重写
    2. 一旦子类重写了模板方法,模板方法就失效了。
  4. 抽象类中的方法不一定是公开的,不一定都是public哦
java 复制代码
//父类People------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract3;

public abstract class People {
    public void write(){
        System.out.println("第一行相同的");
        System.out.println("第二行相同的");
//        System.out.println("第三行是不相同3a6adf168a4sd64的");这里是不一样的,所以这里不能写死,可以写一个抽象方法。
        write1();
        System.out.println("第四行相同的");
    }

    public abstract void write1();
}

//子类Teacher------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract3;

public class Teacher extends  People{
//    public void write(){
//        System.out.println("第一行相同的");
//        System.out.println("第二行相同的");
//        System.out.println("第三行是不相同这里是老师专属的");
//        System.out.println("第四行相同的");
//
//    }
    public void write1(){
        System.out.println("第三行是不相同这里是老师专属的");
    }

}

//子类Stdent------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract3;

public class Student extends People {
//    public void write(){
//        System.out.println("第一行相同的");
//        System.out.println("第二行相同的");
//        System.out.println("第三行是不相同这里是学生专属的");
//        System.out.println("第四行相同的");
//    }
    public void write1(){
        System.out.println("第三行是不相同这里是学生专属的");
    }
}
java 复制代码
//Test------------------------------------------------------------------------------------------------------------------------------------------------------
package com.itheima.abstract3;

public class Test {
    public static void main(String[] args) {
        //目标:理解抽象类的使用场景之一,模板方法设计模式。
        //学生和老师都要写一篇作文:《我的爸爸》
        //          第一段是一样的,我的爸爸是一个XXX,是一个好人,我来介绍一下。
        //          第二段是不一样的,老师和学生各自写各自的。
        //          第三段是一样的,我的爸爸真好,你有这样的爸爸吗?
        People p = new Teacher();
        p.write();
        People t = new Student();
        t.write();
    }
}

小结:

  1. 模板方法设计模式解决了什么问题?
    1. 解决方法中存在重复代码的问题。
  2. 模板方法设计模式应该怎么写?
    1. 定义一个抽象类
    2. 在里面定义两个方法,一个是模板方法:放相同的代码里,一个是抽象方法:具体实现交给子类完成。
  3. 模板方法建议使用什么关键字修饰吗?为什么?
    1. 建议使用final关键字修饰模板方法。

------------java基础d7--08---接口-认识接口---------------------------------------------------------------------------

interface 接口

  1. java提供了一个关键字interface定义出接口

  2. 格式:

    1. public interface 接口名{

      //成员变量(常量)

      //成员方法(抽象方法)

      }

  3. JDK8及之前,接口只能写常量和抽象方法。

  4. 接口特点

    1. 接口变量的public、static、final不写,会自动给加上。

    2. 方法的public abstract也会自动加上。

    3. 绝对不能创建对象

    4. 接口不叫继承,叫被类实现, 实现接口的类称为实现类。

      1. 一个类可以同时实现多个接口

      2. 修饰符 class 实现类类名 。implements 接口1,接口2,接口3,......{}

小结:

  1. 接口是什么?
    1. 使用interface关键字定义的一种结构,JDK8之前,接口中只能定义成员变量和成员方法。
  2. 接口怎么使用?需要注意什么?
    1. 接口是被 类 实现的。
    2. 实现类实现多个接口,必须重写完接口的全部抽象方法,否则实现类需要定义成抽象类。

------------java基础d7--09---接口-接口的好处------------------------------------------------------------------------

接口的好处:

  1. 接口的好处:
    1. 弥补了类单继承的不足,一个类同时可以实现多个接口,使类的角色更多,功能更强大。
    2. 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。(更有利于程序的解耦合)

比如我们是A公司,我们要开发一个产品,但是不知道选B公司好还是C公司好,那么准备好几个接口,大家开始开发。搞完之后,用上接口先new B试一下,不行的话就换一个new C就可以了,剩下的上千行代码不用动。

------------java基础d7--10---接口-综合小案例------------------------------------------------------------------------

需求:

  1. 设计一个班级学生的信息管理模块:学生是数据有:姓名、性别、成绩

    1. 功能1:要求打印出全班学生的信息
    2. 功能2:要求打印出全班学生的平均信息
  2. 注意:以上功能的业务实现是有多套方案的,比如:

    1. 第一套:能打印出班级全部学生的信息;能够打印班级全部学生的平均分。
    2. 第二套:能打印出班级全部学生的信息(包括男女人数);能打印班级全部学生的平均分(去掉最高分、最低分)
  3. 系统可以支持灵活的切换这些实现方案。

    //学生类,储存学生信息------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.interface3;

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
    private String name;
    private char sex;
    private double score;

    }

    //父类,接口类------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.interface3;

    public interface ClassDataInter {
    void printAllStudentInfos();
    void printAverageScore();
    }

    //子类1 方法1------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.interface3;

    public class ClassDataInterImpl1 implements ClassDataInter{
    private Student[] students;
    public ClassDataInterImpl1(Student[] students) {
    this.students = students;
    }
    @Override
    public void printAllStudentInfos() {
    System.out.println("所有学生信息如下:");
    for (int i = 0; i < students.length; i++) {
    Student s = students[i];
    System.out.println("第" + (i+1) + "个学生信息:" + s.getName() + " " + s.getSex() + " " + s.getScore());

    复制代码
         }
    
     }
    
     @Override
     public void printAverageScore() {
         System.out.println("所有学生的平均分是:");
         double sum = 0;
         for (int i = 0; i < students.length; i++) {
             Student s = students[i];
             sum += s.getScore();
         }
         System.out.println(sum / students.length);
    
     }

    }

    //子类2 方法2------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.interface3;

    public class ClassDataInterImpl2 implements ClassDataInter{
    private Student[] students;
    public ClassDataInterImpl2(Student[] students) {
    this.students = students;
    }
    @Override
    public void printAllStudentInfos() {
    int manCount = 0;
    for (int i = 0; i < students.length; i++) {
    Student s = students[i];
    System.out.println("第" + (i+1) + "个学生信息:" + s.getName() + " " + s.getSex() + " " + s.getScore());
    if(s.getSex() == '男'){
    manCount++;
    }
    }
    System.out.println("男生人数:" + manCount);
    System.out.println("女生人数:" + (students.length-manCount));
    }

    复制代码
     @Override
     public void printAverageScore() {
         System.out.println("所有学生的平均分是:");
         double sum = 0;
         double max = students[0].getScore();
         double min = students[0].getScore();
         for (int i = 0; i < students.length; i++) {
             Student s = students[i];
             if(s.getScore() > max){
                 max = s.getScore();
             }
             if(s.getScore() < min){
                 min = s.getScore();
             }
             sum += s.getScore();
         }
         sum -= max;
         sum -= min;
         System.out.println("最高分:" + max);
         System.out.println("最低分:" + min);
         System.out.println("平均分:" + sum / (students.length-2));
     }

    }

    //main方法------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.interface3;

    public class Test {
    public static void main(String[] args) {
    //目标:完成接口的小案例。
    //1、首先定义一个学生类,创建学生对象,封装学生数据,才能交给别人处理学生的数据。
    //2、准备学生数据,目前我们自己造一些测试数据。
    //
    Student s1 = new Student("小王",'男',99.5);
    Student s2 = new Student("小张",'女',98.5);
    Student s3 = new Student("小李",'男',97.5);
    Student s4 = new Student("小赵",'女',96.5);
    Student s5 = new Student("小孙",'男',95.5);
    Student s6 = new Student("小钱",'女',94.5);
    Student s7 = new Student("小周",'男',93.5);
    Student s8 = new Student("小吴",'女',92.5);
    Student s9 = new Student("小郑",'男',91.5);
    Student s10 = new Student("小王",'女',10.5);
    Student[] students = {s1,s2,s3,s4,s5,s6,s7,s8,s9,s10};
    //3、准备两套业务实现方案。支持灵活切换(解耦合);
    // --定义一个接口,规范思想,必须完成打印全部学生信息,打印平均分;
    // --定义第一套实现类,实现啊接口:实现打印学生信息,实现打印平均分。
    // --定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印最高分(去掉最高分和最低分)。

    复制代码
         ClassDataInter cdi = new ClassDataInterImpl1(students);
         cdi.printAllStudentInfos();
         cdi.printAverageScore();
         ClassDataInter cdi2 = new ClassDataInterImpl2(students);
         cdi2.printAllStudentInfos();
         cdi2.printAverageScore();
     }

    }

------------java基础d7--11---接口-JDK8新增的三个方法,几点注意事项------------------------------------

  1. 新增:默认方法(实例方法、default)、私有方法(private)、类方法(静态方法、static)

    1. 默认方法,default void test1(){}默认带public
      1.

      java 复制代码
          //1、默认方法(普通的实例方法);必须加default修饰,系统会默认加public
          //调用:使用实现类的对象来调用。
          default void show(){
              System.out.println("默认的方法show()");
              show2();    //调用一下show2();
          }

      如何调用?

      1. 使用实现类的对象来调用。
    2. 私有方法(JDK9才支持的)

      java 复制代码
          //2、私有方法,私有的实例方法。
          // //调用:只能用接口中其他方法来调用(接口没对象,接口没法调;实现类又不能调用接口的私有方法)
          private void show2(){
              System.out.println("私有的实例方法show2()");
          }

      如何调用?

      1. 只能用接口中其他方法来调用(接口没对象,接口没法调;实现类又不能调用接口的私有方法)
    3. 类方法/静态方法:

      java 复制代码
          //3、静态方法,系统会默认加public修饰;
          //调用:只能使用当前接口名来调用。
          static void show3(){
              System.out.println("静态的私有的实例方法show3()");
          }

      如何调用?

      1. 只能使用当前接口名来调用。
    4. 调用:

      java 复制代码
      public class Test {
          public static void main(String[] args) {
              //目标:搞清楚接口新增的三种方法,并理解其好处。
              B b = new B();
              b.show();        //子类对象.默认方法
      //        b.show2();//只能用其他方法调用,这里写到show()里面了。
              A.show3();    //接口名.静态方法
      
          }
      }
      
      class B implements A{
      }
  2. 作用:

    1. 增强了接口的能力(功能更多了)

    2. 更便于项目的扩展和维护;

      1. 比如一个接口有好几百个实现类,项目已经上线了,现在要在接口中加一个方法,那以前的话,只能加抽象方法,几百个实现类全都会报错。新增功能后,实现类不需要重写方法,就更方便维护嘛。

小结:

  1. JDK8开始,接口中新增了哪些方法?
    1. 默认方法,使用default修饰,使用实现类的对象调用
    2. 私有方法,private修饰,JDK9才开始有的,只能在接口内部被调用
    3. 静态方法,static修饰,必须使用当前接口名调用
    4. 他们都默认被public修饰
  2. JDK8开始,接口中为啥要新增这些方法?
    1. 增强了接口的能力,更便于项目的扩展和维护。

接口的注意事项:

  1. 接口与接口可以多继承:一个接口可以同时继承多个接口[重点]
  2. 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。
  3. 一个类继承了父类,有同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。
  4. 一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
java 复制代码
package com.itheima.interface5;

public class Test {
    public static void main(String[] args) {
        //目标:理解接口的几点注意事项
//        1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]
//        2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。
//        3、一个类继承了父类,有同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。
        C3 c3 = new C3();
        c3.show();
        c3.go();//了解,中转一下,即在子类中重写一个方法,专门去调用接口父类中的方法:A3.super.show();
//        4、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
        C4 c4 = new C4();
        c4.show();
        c4.showB();
        c4.showA();
    }
}
//        1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]
//类与类:单继承,一个类只能继承一个直接父类。
//类与接口:多实现,一个类可以实现多个接口。
//接口与接口:多继承,一个接口可以继承多个接口。
interface A1{
    void show1();
}
interface B1{
    void show2();
}
interface C1 extends A1,B1{
    void show3();
}
class D implements C1{

    @Override
    public void show3() {

    }

    @Override
    public void show1() {

    }

    @Override
    public void show2() {

    }
}

//        2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。

interface A2{
    void show();    //同样的方法名没有返回值
}
interface B2{
    String show();  //同样的方法名有返回值
}
//interface C2 extends A2,B2{
//    void show();  //冲突报错。
//}
//class D2 implements C2{

//    @Override
//    public void show() {
//    }

//}

//        3、一个类继承了父类,有同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。

interface A3{
    default void show(){
        System.out.println("A3的show()");
    }
}

class B3{
    public void show(){
        System.out.println("B3的show()");
    }
}

class C3 extends B3 implements A3{
    //了解:也可以调用接口父类的重名方法,但是要中转:
    public void go(){
        A3.super.show();
    }
}

//        4、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。

interface A4{
    default void show(){
        System.out.println("A4的show()");
    }
}
interface B4{
    default void show(){
        System.out.println("B4的show()");
    }
}
class C4 implements A4,B4{
    @Override
    public void show(){
        System.out.println("C4的show()");
    };
    public void showB(){
        B4.super.show();
    }
    public void showA(){
        A4.super.show();
    }
}

------------java基础d7--12---接口-抽象类和接口的区别------------------------------------------------------------

抽象类和接口的区别对比:

复制代码
找相同点:
        1、都是抽象形式,都可以有抽象方法、都不能创建对象。
        2、都是派生子类形式:抽象类是被子类继承使用,接口是被是实现类实现。
        3、继承抽象类或者实现接口,都必须重写完他们的抽象方法,否则自己变成抽象类或者报错。
        4、都能支持多态。都能够实现解耦合。



不同点:
        1、抽象类中可以定义类的全部普通成员,
                接口只能定义常量、抽象方法、JDK8新增的三种方法。
        2、抽象类中只能被类单继承,
                接口可以被类多实现。
        3、一个类继承抽象类,就不能 再继承其他类,
                一个类实现了接口,还可以继承其他类或者实现其他接口。
        4、抽象类体现模板思想,更利于做父类实现代码的复用性,(IO流?)
                接口更适合做功能的解耦合,解耦合性更强。解耦合性更强、更灵活。(集合?)

------------java基础d7--13---综合项目-智能家居系统---------------------------------------------------------------

需求:

某智能家居系统、可以让用户选择要控制的家用设备(吊灯、电视、落地窗),并可以对他们进行打开或者关闭操作。

PS:boolean布尔值的变量使用时,会变成is+变量名(首字母大写):

比如

复制代码
private boolean status; //————》 isStatus()

代码:

  1. 父类JD

    java 复制代码
    package com.itheima.demo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class JD implements  Switch{
        //家电的父类,名称、状态(开或关)
        private String name;
        private boolean status; //默认是false
    
        @Override
        public void press() {
            //控制当前设备的开和关
            System.out.println("按下了开关");
            status = !status;
        }
    }

    123

  2. 父类接口Switch

    java 复制代码
    package com.itheima.demo;
    
    public interface Switch {
        void press();
    }

    123

  3. 各个家电子类:

    java 复制代码
    //吊顶------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.demo;
    
    public class Lamp extends JD{
        //吊灯类
        public Lamp(String name, boolean status) {
            super(name, status);
        }
    
    }
    
    //洗衣机------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.demo;
    
    public class WashMachine extends JD{
        //洗衣机
        public WashMachine (String name , boolean status){
            super(name,status);
        }
    }
    
    //电视机------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.demo;
    
    public class TV extends JD{
        //电视机
        public TV(String name , boolean status){
            super(name,status);
        }
    }
    
    //空调------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    package com.itheima.demo;
    
    public class Air extends JD{
        //空调
        public Air(String name, boolean status) {
            super(name, status);
        }
    }
  4. 智能控制系统类(这里设计成了单例类)

    java 复制代码
    package com.itheima.demo;
    //智能控制系统类
    //搞成单例类。只需要一个就行。
    public class SmartHomeControl {
        private static final SmartHomeControl smartHomeControl = new SmartHomeControl();
        private SmartHomeControl(){};
        public static SmartHomeControl getInstance(){
            return smartHomeControl;
        }
        //多态
        public void control(JD jd){
            System.out.println(jd.getName() + "的状态现在是" + (jd.isStatus() ? "开着" : "关着"));
            System.out.println("控制了:" + jd.getName());
            jd.press();
            System.out.println("动作完毕,现在" + jd.getName() + "的状态已经是" + (jd.isStatus() ? "开着" : "关着"));
            System.out.println("---------------------------------------------------------------------------");
        }
    
        public void printAll(JD[] jds){
            for (int i = 0; i < jds.length; i++) {
                System.out.println("家电的编号" +i + ":"+ jds[i].getName() + "的状态是" + (jds[i].isStatus() ? "开着" : "关着"));
            }
            System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
        }
    }

    123

  5. main主函数:

    java 复制代码
    package com.itheima.demo;
    
    import java.util.Scanner;
    
    public class Test {
        public static void main(String[] args) {
            // 目标:面向对象编程实现智能家居控制系统。
            //角色:设备(吊灯、洗衣机、电视机、空调)
            //具备的功能:开和关
            //谁控制他们,只能控制系统(单例对象),,控制调用设备的开和关。
    
            //1、定义设备类、创建设备对象代表家里的设备。
            //2、准备这些设备对象,放到一个数组中。代表整个家庭的设备。
            JD jds[] = new JD[4];
            jds[0] = new Lamp("吊灯",true);
            jds[1] = new WashMachine("洗衣机",false);
            jds[2] = new TV("电视机",true);
            jds[3] = new Air("空调",false);
    
            //3、创建每个设备的开和关的功能。
            //4、创建一个智能控制的对象,控制设备。
    //        SmartHomeControl smartHomeControl = new SmartHomeControl();
            SmartHomeControl smartHomeControl = SmartHomeControl.getInstance();
            //5、控制一下吊灯
    //        smartHomeControl.control(jds[0]);
            //6、提示用户操作。a、要展示设备全部的开关情况,b、让用户选择一个操作。
            //首先要打印设备全部的开合关的状态。
            while (true){
                smartHomeControl.printAll(jds);
                System.out.println("请输入要操作的设备编号:");
                Scanner sc = new Scanner(System.in);
                int index = sc.nextInt();
                switch (index){
                    case 1:
                        smartHomeControl.control(jds[0]);
                        break;
                    case 2:
                        smartHomeControl.control(jds[1]);
                        break;
                    case 3:
                        smartHomeControl.control(jds[2]);
                        break;
                    case 4:
                        smartHomeControl.control(jds[3]);
                        break;
                    case 0:
                        System.out.println("已退出");
                        return;
                    default:
                        System.out.println("输入的编号有误");
                }
            }
            //
    
        }
    }
相关推荐
小坏讲微服务43 分钟前
Spring Boot 4.0 整合 RabbitMQ 注解方式使用指南
java·spring boot·rabbitmq·java-rabbitmq
big-seal44 分钟前
分页列表中能够按照名称查询,使用 mybatis 的 Example 动态构造 SQL where 条件
java·开发语言
福尔摩斯张1 小时前
C语言文件操作详解(一):文件的打开与关闭(详细)
java·linux·运维·服务器·c语言·数据结构·算法
white-persist1 小时前
【攻防世界】reverse | answer_to_everything 详细题解 WP
c语言·开发语言·汇编·python·算法·网络安全·everything
廋到被风吹走1 小时前
【Spring】依赖注入的实现方式对比
java·spring
lly2024061 小时前
Go 语言数组
开发语言
Zzzzzxl_1 小时前
互联网大厂Java/Agent面试实战:Spring Boot、JVM、微服务与AI Agent/RAG场景问答
java·jvm·spring boot·ai·agent·rag·microservices
FreeBuf_1 小时前
恶意 Rust 包瞄准 Web3 开发者窃取加密货币
开发语言·rust·web3
未若君雅裁1 小时前
JVM高级篇总结笔记
java·jvm·笔记