------------java基础d7--01---final关键字-详解-Java常量---------------------------------------------------------
面向对象高级:final、单例类、枚举类、抽象类、接口
final:最终。可以修饰类、方法、变量。
大概的作用:
- 修饰类:该类被称为最终类,特点是不能被继承了。
- 修饰方法:该方法被称为最终方法,特点是不能被重写了。
- 修饰变量:该变量有且仅能被赋值一次。
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值就不能被修改。相当于给他保护起来了。
}
}
注意:
- final修饰基本类型的变量,变量存储的数据不能被改变。
- final修饰引用类型的变量,变量储存的地址不能被改变,但地址所指向的内容是可以被改变的。
常量的使用:
-
使用了static final修饰的成员变量就被称为常量。
- 作用:常用于记录系统的配置信息。
javapublic class Constant{ public static final String SCHOOL_NAME = "传智教育"; }常量的名称全用大写字母,单词之间用下划线链接。
3. 企业开发时,会单独搞一个Constant包,专门用来存放常量。 -
使用常量记录系统配置信息的优势、执行原理:
-
代码可读性更好,可维护性也更好。
-
疑问:开发中用常量,会不会导致性能不好?还要寻址,找包找变量的?
-
对性能没有影响,程序编译后,常量会被宏替换:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接字面量的性能是一样的。
javapackage com.itheima.finaldemo; public class Constant { //常量包。 public static final String SYSTEM_NAME = "传智播客"; }javapackage 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---单例设计模式-懒汉式单例-饿汉式单例------------------------------------------
什么是设计模式?
- 一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式
- 设计模式有20多种,对应20多种软件开发中会遇到的问题。
- 关于设计模式主要学什么?
- 解决什么问题?
- 怎么写?
单例设计模式:
- 作用:确保某个类只能创建一个对象。
- 比如电脑的任务管理器,只有一个,不管启动多少次,只能有一个。
- 写法?实现步骤?
- 把类的构造器私有。
- 定义一个类变量记住类的一个对象。
- 定义一个类方法,返回对象。
- 单例类有很多种形式,比如
-
饿汉式单例:拿对象时,对象早就创建好了:
1.javapackage 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; // } }阿巴
-
懒汉式单例:拿对象时,才开始创建对象。
-
实现步骤:
-
把类的构造器私有;
-
定义一个静态比哪里用于存储对象,
-
提供一个静态方法,保证返回的是同一个对象。
-
-
代码:
javapackage 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; } }
-
-
小结:
- 什么是设计模式,设计模式主要学什么?单例模式解决了什么问题?
- 具体问题的最优解决方案。
- 解决了什么问题?怎么写?
- 确保某个类只能创建一个对象。
- 单例怎么写?饿汉式单例的特点是什么?
- 把类的构造器私有,定义一个静态变量存储类的一个对象,提供一个静态对象返回对象。
- 在获取类的对象时,对象已经创建好了。
- 单例有啥应用场景?有啥好处?
- 任务管理器对象、获取运行时对象。
- 在这些业务场景下,使用单例模式,可以避免浪费内存。
- 懒汉单例模式的特点是什么?
- 要用类的对象时才创建对象(延迟加载对象)
- 兰花单例模式怎么写?
- 把构造器私有
- 定义一个类变量用于存储对象。
- 提供一个类方法,保证返回的是同一个对象。
------------java基础d7--03---枚举-认识枚举---------------------------------------------------------------------------
-
枚举类是一种特殊类。
-
格式
-
修饰符 enum 枚举类名{
名称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就是一个单例类)
-
枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
-
编译器为枚举类新增了几个方法。
-
枚举类重写了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---枚举-应用场景---------------------------------------------------------------------------
- 常见应用场景:
- 适合做信息分类和标志。
- 比如,做数字华容道的时候,用来接收上下左右四个方向的时候,可以用枚举。
- 适合做信息分类和标志。
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;;
-
abstract意思是抽象,可以修饰类、成员方法。
- 修饰类,就是抽象类;
- 修饰方法,就是抽象方法。
-
格式:
-
修饰符 abstract class 类名{
修饰符 abstract 返回值类型 方法名称(形参列表);
}
javapublic abstract class A{ //抽象方法:必须abstract修饰,只有方法前面,不能有方法体。 public abstract void test(); }
-
-
注意事项、特点:
-
抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类;
-
类的成员:成员变量、方法、构造器、抽象类都可以有。
-
抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
-
一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义为抽象类。(抽象类的使命就是被继承)
-
小结:
- 抽象类、抽象方法是什么样的?
- 都是用abstract修饰的,抽象方法只有方法签名,不能写方法体。
- 抽象类有哪些注意事项和特点?
- 抽象类中可以不写抽象方法,但有抽象方法的类必须是抽象类。
- 类的成员(成员变量、方法、构造器)抽象类都具备。
- 抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
- 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
------------java基础d7--06---抽象类-好处、应用场景---------------------------------------------------------------
抽象类的好处:
- 父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,
- 设计这样的抽象类,就是为了更好的支持多态。
- 最佳实践,写抽象类比写普通类的父类更优雅。
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---抽象类-模板方法设计模式------------------------------------------------------------
- 模板方法设计模式:
- 提供一个方法作为完成某类功能的模板,模板方法封装了每个实现步骤,但运行子类提供特定步骤的实现。
- 模板方法设计模式可以:
- 提供代码的复用、
- 并简化子类设计。
- 写法:
- 定义一个抽象类
- 在里面定义两个方法:
- 一个是模板方法:把相同的实现步骤放到里面去;
- 一个是抽象方法:不确定的实现步骤,交给具体的子类案来完成。
- 多学一找:建议使用final关键字修饰模板方法。
- 因为模板方法就是给子类直接使用的,不建议被子类重写
- 一旦子类重写了模板方法,模板方法就失效了。
- 抽象类中的方法不一定是公开的,不一定都是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();
}
}
小结:
- 模板方法设计模式解决了什么问题?
- 解决方法中存在重复代码的问题。
- 模板方法设计模式应该怎么写?
- 定义一个抽象类
- 在里面定义两个方法,一个是模板方法:放相同的代码里,一个是抽象方法:具体实现交给子类完成。
- 模板方法建议使用什么关键字修饰吗?为什么?
- 建议使用final关键字修饰模板方法。
------------java基础d7--08---接口-认识接口---------------------------------------------------------------------------
interface 接口
-
java提供了一个关键字interface定义出接口
-
格式:
-
public interface 接口名{
//成员变量(常量)
//成员方法(抽象方法)
}
-
-
JDK8及之前,接口只能写常量和抽象方法。
-
接口特点
-
接口变量的public、static、final不写,会自动给加上。
-
方法的public abstract也会自动加上。
-
绝对不能创建对象
-
接口不叫继承,叫被类实现, 实现接口的类称为实现类。
-
一个类可以同时实现多个接口
-
修饰符 class 实现类类名 。implements 接口1,接口2,接口3,......{}
-
-
小结:
- 接口是什么?
- 使用interface关键字定义的一种结构,JDK8之前,接口中只能定义成员变量和成员方法。
- 接口怎么使用?需要注意什么?
- 接口是被 类 实现的。
- 实现类实现多个接口,必须重写完接口的全部抽象方法,否则实现类需要定义成抽象类。
------------java基础d7--09---接口-接口的好处------------------------------------------------------------------------
接口的好处:
- 接口的好处:
- 弥补了类单继承的不足,一个类同时可以实现多个接口,使类的角色更多,功能更强大。
- 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。(更有利于程序的解耦合)

比如我们是A公司,我们要开发一个产品,但是不知道选B公司好还是C公司好,那么准备好几个接口,大家开始开发。搞完之后,用上接口先new B试一下,不行的话就换一个new C就可以了,剩下的上千行代码不用动。
------------java基础d7--10---接口-综合小案例------------------------------------------------------------------------
需求:
-
设计一个班级学生的信息管理模块:学生是数据有:姓名、性别、成绩
- 功能1:要求打印出全班学生的信息
- 功能2:要求打印出全班学生的平均信息
-
注意:以上功能的业务实现是有多套方案的,比如:
- 第一套:能打印出班级全部学生的信息;能够打印班级全部学生的平均分。
- 第二套:能打印出班级全部学生的信息(包括男女人数);能打印班级全部学生的平均分(去掉最高分、最低分)
-
系统可以支持灵活的切换这些实现方案。
//学生类,储存学生信息------------------------------------------------------------------------------------------------------------------------------------------------
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新增的三个方法,几点注意事项------------------------------------
-
新增:默认方法(实例方法、default)、私有方法(private)、类方法(静态方法、static)
-
默认方法,default void test1(){}默认带public
1.java//1、默认方法(普通的实例方法);必须加default修饰,系统会默认加public //调用:使用实现类的对象来调用。 default void show(){ System.out.println("默认的方法show()"); show2(); //调用一下show2(); }如何调用?
- 使用实现类的对象来调用。
-
私有方法(JDK9才支持的)
java//2、私有方法,私有的实例方法。 // //调用:只能用接口中其他方法来调用(接口没对象,接口没法调;实现类又不能调用接口的私有方法) private void show2(){ System.out.println("私有的实例方法show2()"); }如何调用?
- 只能用接口中其他方法来调用(接口没对象,接口没法调;实现类又不能调用接口的私有方法)
-
类方法/静态方法:
java//3、静态方法,系统会默认加public修饰; //调用:只能使用当前接口名来调用。 static void show3(){ System.out.println("静态的私有的实例方法show3()"); }如何调用?
- 只能使用当前接口名来调用。
-
调用:
javapublic class Test { public static void main(String[] args) { //目标:搞清楚接口新增的三种方法,并理解其好处。 B b = new B(); b.show(); //子类对象.默认方法 // b.show2();//只能用其他方法调用,这里写到show()里面了。 A.show3(); //接口名.静态方法 } } class B implements A{ }
-
-
作用:
-
增强了接口的能力(功能更多了)
-
更便于项目的扩展和维护;
- 比如一个接口有好几百个实现类,项目已经上线了,现在要在接口中加一个方法,那以前的话,只能加抽象方法,几百个实现类全都会报错。新增功能后,实现类不需要重写方法,就更方便维护嘛。
-
小结:
- JDK8开始,接口中新增了哪些方法?
- 默认方法,使用default修饰,使用实现类的对象调用
- 私有方法,private修饰,JDK9才开始有的,只能在接口内部被调用
- 静态方法,static修饰,必须使用当前接口名调用
- 他们都默认被public修饰
- JDK8开始,接口中为啥要新增这些方法?
- 增强了接口的能力,更便于项目的扩展和维护。
接口的注意事项:
- 接口与接口可以多继承:一个接口可以同时继承多个接口[重点]
- 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。
- 一个类继承了父类,有同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。
- 一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
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()
代码:
-
父类JD
javapackage 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
-
父类接口Switch
javapackage com.itheima.demo; public interface Switch { void press(); }123
-
各个家电子类:
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); } } -
智能控制系统类(这里设计成了单例类)
javapackage 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
-
main主函数:
javapackage 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("输入的编号有误"); } } // } }