Java
day9——2023.8.16
提供一个整理的面向对象,设计模型超链接
设计模型知识点
接口
Java中的接口
概念 :接口就是一种规则,也是一种约束,实现类必须要遵守接口中定义的信息,并且还可以解决单继承的局限性
接口的特点:
写法 : 使用interface关键字,其实就是将类的class换成interface
public interface 接口名{}
子类实现接口
class 类名 implements 接口名{ }
interface 子接口 extends 父接口{}
其他特点
1,接口不能被实例化
2,接口的实现类 ,
可以是一个具体类,具体类中,必须要实现父接口的全部抽象方法
可以是一个抽象类,抽象类可以不用实现全部抽象方法
3,成员特点:
成员变量
成员变量只能是常量,默认的修饰符是 : public static final
构造方法
接口中没有构造方法
成员方法
默认只能存在抽象方法,默认修饰符就是 public abstract
jdk8针对接口的不容易扩展现象,增加了static 和 default方法,如果定义这两个方法,方法中必须要写方法体用来实现某些功能,主要用来增加接口的灵活性
jdk9之后,在接口中又增加了私有private修饰的方法和private修饰的静态方法,这些私有的方法,主要可以改善接口内部代码的可重用性
public interface Person {
void say();
}
public interface Father extends Person {
//接口中的成员变量只能是常量,即使变量之前没有加final,仍然默认会去添加final
String name = "jack";
//public Father();
//接口中可以有抽象方法
public abstract void playFootBall();
//普通方法,接口中不能有普通方法
// public void method(){
//
// }
//静态方法,接口中可以有静态方法
public static void method01(){
}
//默认方法,接口中可以存在默认方法,使用default修饰的
default void method02(){
}
}
public interface Mother extends Person {
void sing();
}
public class Son implements Father,Mother {
@Override
public void playFootBall() {
System.out.println("儿子会踢球");
}
@Override
public void sing() {
System.out.println("儿子会唱歌");
}
@Override
public void say() {
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.playFootBall();
son.sing();
//son.name = "tom"; //name是用final修饰的,是常量
System.out.println(son.name);
//new Father(); //接口不能被实例化
}
}
设计一个简单的USB接口
//usb接口
public interface USBInterface {
void service();
}
/*
U盘类
*/
public class UDisk implements USBInterface {
@Override
public void service() {
System.out.println("连接USB,U盘开始工作!");
}
}
//鼠标类
public class UMouse implements USBInterface {
@Override
public void service() {
System.out.println("鼠标连接上USB接口,开始工作!");
}
}
public class Test {
public static void main(String[] args) {
//多态创建接口对象
USBInterface usb = new UDisk();
usb.service();
USBInterface usb1 = new UMouse();
usb1.service();
}
}
抽象类和接口的比较
内部类
概念 : 把类定义在其他类的内部,这个类就被称为内部类
特点 : 内部类可以直接访问外部类的成员,包括私有的
外部类要访问内部类的成员,需要创建对象
分类 :
定义在成员位置 :称为成员内部类
定义在局部位置:一般指的是定义在外部类类的方法中,称为局部内部类
public class Outer {
private int num = 100; //外部类的私有属性
//成员内部类
class Inner{
}
//外部类的成员方法
public void method(){
//局部内部类
class Inner{
}
}
}
成员内部类
普通成员内部类
public class Outer {
private int num = 100; //外部类的私有属性
private static int num1 = 200;
//成员内部类
class Inner{
//内部类可以使用的修饰符
//private static
//内部类的普通方法
public void show(){
//内部类加了static之后,只能访问外部类中加了static的属性
System.out.println(num);
System.out.println(num1);
}
//如果内部类没有static,内部不能定义static方法
//public static void show2(){
// //System.out.println(num);
// System.out.println(num1);
//}
}
}
public class InnerDemo {
public static void main(String[] args) {
//创建内部类的对象的写法 :
//外部类名.内部类名 对象名 = 外部类对象.内部类对象
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
静态成员内部类
public class Outer {
private int num = 100; //外部类的私有属性
private static int num1 = 200;
//成员内部类
static class Inner{
//内部类可以使用的修饰符
//private static
//内部类的普通方法
public void show(){
//内部类加了static之后,只能访问外部类中加了static的属性
//System.out.println(num);
System.out.println(num1);
}
//如果内部类没有static,内部不能定义static方法
public static void show2(){
//System.out.println(num);
System.out.println(num1);
}
}
}
public class InnerDemo {
public static void main(String[] args) {
//静态的内部类对象创建方式:
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner inner1 = new Outer.Inner();
inner1.show();
inner1.show2();
//静态内部类中的静态方法,可以通过类名直接访问
Outer.Inner.show2();
//Outer.Inner.show();
}
}
局部内部类
1,可以直接访问外部类的成员
2,可以在局部位置,创建内部类的对象,通过对象调用内部类的方法,从而来使用局部内部类的功能
public class Outer {
private String str = "hello";
public void method(String a){
//局部内部类
class Inner{
//内部类的成员方法
public void show(){
System.out.println(str); //直接访问外部类的成员属性
System.out.println(a); //访问局部变量
}
}
//在局部位置,直接创建内部类的对象
Inner inner = new Inner();
inner.show();
}
}
public class InnerTest {
public static void main(String[] args) {
//创建外部类对象,通过外部类对象直接调用成员方法
//从而调用到成员方法中的局部内部类
Outer outer = new Outer();
outer.method("你好");
}
}
局部内部类访问局部变量的时候的问题
1,局部内部类访问的局部变量,必须是用final修饰的
为什么?
局部变量是随着方法的调用而存在,方法调用完毕而消失
局部内部类对象是在堆中,堆中的内容不会马上消失,所以如果不加final修饰,可能会出现一个没有消失的对象,在调用已经消失的局部变量,这种情况是不合理的。
加了final修饰后,变量就变为常量了,消失之后内存中的数据还是存在
jdk8之后,局部内部类的局部变量,即使没有加上final,系统也会默认变量是final的
匿名内部类
匿名内部类是内部类的简化写法
需要前提 :需要存在一个类或者接口,这个类可以是具体类,也可以是抽象类
new 类名或者接口名(){
重写方法;
}
public interface Inner {
void show1();
void show2();
}
public class Outer {
//外部类的成员方法
public void method(){
//这个操作,相当于在创建接口的实现类
//这个实现类,没有名字,称为匿名内部类
//相当于把实现Inner接口的实现类,和实现类的对象都创建了
//完成了4个动作 :
// 1,Inner接口实现类的创建 2,接口方法的重写 3,实现类对象的创建 4,重写方法的调用
/* new Inner(){
//实现接口中的方法
@Override
public void show1() {
System.out.println("匿名内部类重写的show1方法~");
}
@Override
public void show2() {
System.out.println("匿名内部类重写的show2方法~");
}
}.show1();
//接口中有多个方法的话,写实现就得写多次,比较麻烦
new Inner(){
//实现接口中的方法
@Override
public void show1() {
System.out.println("匿名内部类重写的show1方法~");
}
@Override
public void show2() {
System.out.println("匿名内部类重写的show2方法~");
}
}.show2();
*/
//使用多态来改进写法,父接口的引用指向子类的对象
Inner inner = new Inner(){
//实现接口中的方法
@Override
public void show1() {
System.out.println("匿名内部类重写的show1方法~");
}
@Override
public void show2() {
System.out.println("匿名内部类重写的show2方法~");
}
};
inner.show1();
inner.show2();
}
}
public class OuterTest {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
匿名内部类的笔试题
public interface Inner {
void show();
}
public class Outer {
//等待补齐代码
}
public class OuterTest {
public static void main(String[] args) {
Outer.method().show();
//在后台输出 :"HelloWord!"
}
}
//Outer.method()
//说明存在静态的method()方法
//Outer.method().show() 说明method方法应该返回Inner对象
public static Inner method(){
return new Inner() {
@Override
public void show() {
System.out.println("HelloWorld!");
}
};
}
设计模式
通过设计模式的完成计算器的使用:
基本代码实现
/*
基本代码实现计算器
*/
public class Demo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入计算的第一个数字:");
int a = scanner.nextInt();
System.out.println("请输入运算符号:");
String b = scanner.next();
System.out.println("请输入计算的第二个数字:");
int c = scanner.nextInt();
int result = 0;
switch (b){
case "+":
result = a + c;
break;
case "-":
result = a - c;
break;
case "*":
result = a * c;
break;
case "/":
result = a / c;
break;
default:
System.out.println("运算符输入错误!");
return;
}
System.out.println( a + b + c + "=" +result);
}
}
面向对象实现
//面向对象实现
public class Operation {
public static int getResult(int a,int b,String operate){
int result = 0;
switch (operate){
case "+":
result = a + b;
break;
case "-":
result = a - b;
break;
case "*":
result = a * b;
break;
case "/":
result = a / b;
break;
default:
System.out.println("运算符输入错误!");
break;
}
return result;
}
}
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入计算的第一个数字:");
int a = scanner.nextInt();
System.out.println("请输入运算符号:");
String b = scanner.next();
System.out.println("请输入计算的第二个数字:");
int c = scanner.nextInt();
int result = Operation.getResult(a, c, b);
System.out.println(result);
}
}
利用设计模式的工厂方法模式
//计算类抽象类
public abstract class Operation {
private double num1;
private double num2;
public abstract double getResult();
public double getNum1() {
return num1;
}
public void setNum1(double num1) {
this.num1 = num1;
}
public double getNum2() {
return num2;
}
public void setNum2(double num2) {
this.num2 = num2;
}
}
//加法类
public class Add extends Operation {
@Override
public double getResult() {
return getNum1() + getNum2();
}
}
//减法类
public class Minus extends Operation {
@Override
public double getResult() {
return getNum1() - getNum2();
}
}
//运算工厂类
public class OperationFactory {
public static Operation createOperation(String operate){
if (operate.equals("+")){
return new Add();
}else if (operate.equals("-")){
return new Minus();
}
return null;
}
}
//测试类
public class Test {
public static void main(String[] args) {
Operation o = OperationFactory.createOperation("+");
o.setNum1(10);
o.setNum2(20);
System.out.println(o.getResult());
}
}
利用设计模式的抽象工厂模式:
//计算类抽象类
public abstract class Operation {
private double num1;
private double num2;
public abstract double getResult();
public double getNum1() {
return num1;
}
public void setNum1(double num1) {
this.num1 = num1;
}
public double getNum2() {
return num2;
}
public void setNum2(double num2) {
this.num2 = num2;
}
}
//加法类
public class Add extends Operation {
@Override
public double getResult() {
return getNum1() + getNum2();
}
}
//减法类
public class Minus extends Operation {
@Override
public double getResult() {
return getNum1() - getNum2();
}
}
//计算工厂抽象类
public abstract class OperationFactory {
public abstract Operation createOperation();
}
//加法工厂
public class AddFactory extends OperationFactory {
@Override
public Operation createOperation() {
return new Add();
}
}
//减法工厂
public class MinusFactory extends OperationFactory {
@Override
public Operation createOperation() {
return new Minus();
}
}
//测试类
public class Test {
public static void main(String[] args) {
AddFactory addFactory = new AddFactory();
Operation operation = addFactory.createOperation();
operation.setNum1(10);
operation.setNum2(20);
System.out.println(operation.getResult());
}
}
使用抽象工厂之后,添加一个运算,只要在写子类继承即可:
比如,加个乘法类:
//乘法类
public class ChengFa extends Operation {
@Override
public double getResult() {
return getNum1() * getNum2();
}
}
//乘法工厂
public class ChengFaFactory extends OperationFactory {
@Override
public Operation createOperation() {
return new ChengFa();
}
}
//测试类
ChengFaFactory chengFaFactory = new ChengFaFactory();
Operation operation1 = chengFaFactory.createOperation();
operation1.setNum2(10);
operation1.setNum1(20);
System.out.println(operation1.getResult());