黑马程序员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("输入的编号有误");
                }
            }
            //
    
        }
    }
相关推荐
Scott9999HH36 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔43 分钟前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json