Java面向对象
约 5780 字大约 19 分钟
(1)具体类
1. 类和对象
package model2.unit1;
// 需求:用Java语言表示2个员工:张三30、李四40
// 开发类的步骤:
// 1. 创建一个员工类
// 2. 编写成员变量
// 3. 生成构造方法(无参有参)
// 4. 生成getter和setter方法
// 5. 生成toString方法
// 6. 根据类创建出对象
// 类的概念: 被class关键字修饰的叫做类。
// 类的理解:表示现实生活中的【图纸】或【模板】。
public class Employee {
// 成员变量的概念: 在类中定义的变量叫做成员变量。
// 成员变量的理解:表示类的【属性】或【状态】。
String name;
int age;
// 构造方法的概念:方法名和类同名、并且没有返回值也没有void关键字。
// 构造方法的理解:根据类创建对象所调用的方法。
public Employee() {
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
// 成员方法的概念:在类中定义的方法叫做成员方法。
// 成员方法的理解:表示类的【功能】或【行为】。
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
// 对象的概念:Java语言使用new关键字创建出来的实例叫做对象。
// 对象的理解:表示根据【图纸】或【模板】生产出来制造出来的具体的实体。
// 类【设计图纸】->【调用构造方法】->对象【真实实例】
// 创建对象的语法格式:
// 类名 变量 = new 构造方法
// 调用无参构造方法创建对象
Employee e1 = new Employee();
e1.setName("张三");
e1.setAge(30);
System.out.println(e1);
// 调用有参构造方法创建对象
Employee e2 = new Employee("李四", 40);
System.out.println(e2);
}
}
2. 引用类型
package model2.unit1;
public class Java01 {
public static void main(String[] args) {
// Java语言中数据类型的分类:2种
// 基本数据类型(8个)
// 引用类型(类类型)
// 基本类型和类类型的区别
// 基本类型:存储的是真实的值。
// 引用类型:存储的是对象在内存中的地址的值。
// 值传递:在调用方法的过程中传递参数、返回数据的原理。
// 基本类型传递的是真实的值。
// 引用类型传递的是地址的值。
// 基本数据类型的理解
int a = 2;
m1(a);
System.out.println(a);
// 类类型的理解
int[] c = {1, 2};
m2(c);
System.out.println(c[0]);
}
public static void m2(int[] d) {
d[0] = 3;
}
public static void m1(int b) {
b = 3;
}
public static int m3() {
int a = 3;
return a; // 返回真实的值
}
public static int[] m4() {
int[] x = {1, 2, 3};
return x; // 返回对象地址的值
}
}
3. 引用和实例关系
package model2.unit1;
public class Java02 {
public static void main(String[] args) {
// 引用类型的变量和实例之间的引用关系
// 一个变量可以引用零个或一个对象、一个对象可以被多个变量引用
// null空关键字:只能用于引用类型、表示变量地址为空谁也不引用。
Employee b = new Employee("张三", 30);
Employee c = b;
c.setName("李四");
Employee d = b;
d.setAge(40);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
4. 引用传递原理
package unit2;
public class Java16 {
public static void main(String[] args) {
// 值传递&引用传递
// 基本数据类型传递的是真实的值、引用类型传递的是地址的值(引用传递)。
S s1 = new S("张三");
m(s1);
System.out.println(s1.getName());
}
private static void m(S s2) {
// s2.setName("李四");
s2 = new S("王五");
}
}
class S {
String name;
public S(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5. ==和equals区别
package unit1;
import java.util.Objects;
public class Java05 {
public static void main(String[] args) {
// ==用于基本类型比较的是值、用于引用类型比较的是地址
// equals不能用于基本数据类型、equals方法是Object类中的方法
// 自定义类如果比较相等需要重写equals方法
// String s1 = new String("abc");
// String s2 = new String("abc");
// System.out.println(s1 == s2);
// System.out.println(s1.equals(s2));
// 需求:2个人的名字和年龄如果都一样认为相等
Person p1 = new Person("张三", 30);
Person p2 = new Person("张三", 30);
System.out.println(p1.equals(p2));
}
}
class Person extends Object {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
Person person = (Person)obj;
return (this.getName().equals(person.getName())) && (this.getAge() == person.getAge());
}
}
6. 成员变量和局部变量
package model2.unit1;
public class Java03 {
int a = 2;
public void m() {
int a = 100;
int b = 3;
System.out.println(a);
System.out.println(b);
}
public void m2() {
System.out.println(a);
// System.out.println(b); // b在此作用域不可见
}
public static void main(String[] args) {
// 成员变量和局部变量的区别:
// 成员变量:在类中定义的变量。它的作用范围是整个类的内部都可以使用。
// 局部变量:在方法中定义的变量。它的作用范围是所在方法内部可以使用。
// 关键点理解:查看变量所在的语句块!变量的作用域在所在的语句块中!
int x = 7;
{
int y = 2;
}
{
int z = 4;
}
for (int i = 0; i < 10; i++) {
// 循环体
}
for (int i = 0; i < 10; i++) {
// 循环体
}
}
}
7. 成员变量和局部变量区别
package unit2;
public class Java20 {
static int a;
static void m(int c) {
int b;
System.out.println(a);
}
public static void main(String[] args) {
// 成员变量和局部变量的区别
// 语法:成员变量定义在类中。局部变量定义在语句块或方法块或方法参数中。
// 范围:成员变量作用范围整个类内部。局部变量作用范围是方法内部。
// 成员变量默认值【0、0.0、false、null】。局部变量必须赋值才能使用。
// 存储:成员变量存储在堆内存中(对象在堆内存中)。局部变量存储在栈内存中。
// 生命周期:成员变量随着对象的创建而创建随着对象的销毁而销毁。
// 生命周期:局部变量随着方法的调用而产生随着方法调用结束而销毁。
}
}
8. 关键字:static
package model2.unit1;
public class Java04 {
public Java04() {
}
static int a = 2;
static void m1() {
System.out.println(3);
}
int b = 4;
void m2() {
System.out.println(5);
}
public static void main(String[] args) {
// static关键字:静态
// 被static修饰的静态成员属于类、通过【类名.成员】句式来调用。
// 不被static修饰的非静态成员属于对象、通过【对象.成员】句式来调用。
// 静态成员可以被所有对象共享共用(不建议)
// static关键字使用的场景的判定标准:
// 如果成员变量只需要一份在类中、定义为static成员。
// 如果成员变量在对象中并且每一个对象都需要一份、定义为非static成员。
System.out.println(Java04.a);
Java04.m1();
Java04 x = new Java04();
System.out.println(x.b);
x.m2();
System.out.println(x.a);
x.m1();
}
}
9. 类的加载顺序
package unit1;
public class Java09 {
int a = 2;
static void m(){
// System.out.println(a);
}
public static void main(String[] args) {
// 类的加载顺序
// 一个类的加载顺序:静态成员-非静态成员-构造方法
// 继承类的加载顺序:父静态-子静态-父非静态-父构造-子非静态-子构造
// 注意:静态不能包含非静态!!!
// C c = new C();
E e = new E();
}
}
class C {
static {
System.out.println("静态成员2");
}
static {
System.out.println("静态成员1");
}
{
System.out.println("非静态成员1");
}
{
System.out.println("非静态成员2");
}
public C(){
System.out.println("构造方法");
}
}
class D {
static {
System.out.println("父静态");
}
{
System.out.println("父非静态");
}
public D(){
System.out.println("父构造");
}
}
class E extends D {
static {
System.out.println("子静态");
}
{
System.out.println("子非静态");
}
public E(){
System.out.println("子构造");
}
}
10. 包的使用
package model2.unit1;
public class Java06 {
public static void main(String[] args) {
// 定义包:package 包名;
// 导入包:import 包名.类名;
// 说明:访问本包的类可以直接访问的、访问外包的类必须导入之后才能使用。
// 注意:导入的包不包括子类中的类。
}
}
11. 内部类
package unit4;
public class Java31 {
static class A {
}
class B {
}
void m() {
class C {
}
// 局部内部类
C c = new C();
System.out.println(c);
}
public static void main(String[] args) {
// 内部类(嵌套类)
// 一个类中可以嵌套定义一个类
// 内部类的分类:成员静态内部类、成员非静态内部类、局部内部类、匿名类(没有名字的内部类)
// 静态内部类
Java31.A a = new A();
System.out.println(a);
// 非静态内部类
Java31 x = new Java31();
Java31.B b = x.new B();
System.out.println(b);
x.m();
// 匿名类:【方法实现】和【创建对象】合二为一
Car car1 = new Audi();
car1.drvier();
// 匿名类的实现:
Car car2 = new Car(){
@Override
public void drvier() {
System.out.println("奔驰实现");
}
};
car2.drvier();
// 注意:内部类的编译情况*.java -> *.class
// 外部类$内部类.class
}
}
interface Car {
void drvier();
}
class Audi implements Car {
@Override
public void drvier() {
System.out.println("奥迪实现");
(2)抽象类
1. 抽象类和抽象方法
// 抽象类的概念:被abstract关键字修饰的类叫做抽象类。
// 抽象类的理解:表示抽象的【图纸】或【模板】
// 举例:三角形是具体类、图形就是抽象类。牛马羊是具体类、动物就是抽象类。
public abstract class F {
// 注意:抽象类中有构造方法、但是抽象类不能创建对象。
// 目的:抽象类的目的是以父类的方式管理子类、是一个类的设计工具。
// 抽象方法的概念:被abstract关键字修饰并且没有方法体的方法叫做抽象方法。
// 抽象方法的理解:设计方法的工具、只关注方法的设计、不关心方法的具体实现。
abstract void m1(int a, int b);
abstract boolean m2(double d);
// 注意:抽象类不一定包含抽象方法、包含抽象方法的类一定是抽象类。
}
2. 继承:概念
package model2.unit2;
// 父类
class Father {
int a = 100;
void m() {
System.out.println(200);
}
}
// 继承的概念:子类通过extends关键字继承父类、父类的所有成员子类都有。
// 注意:抽象类和具体类之间可以相互继承、但通常是具体类继承抽象类。
// 注意:类只能继承一个父类。(接口可以同时继承多个父接口)
// 子类Child继承Father
class Child extends Father {
public Child() {
}
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.a);
child.m();
}
}
public class Java07 {
public static void main(String[] args) {
// 继承:父类、子类
// 创建对象的语法格式:
// 类名 变量 = 当前类的对象
Child a = new Child();
// 父类 变量 = 子类的对象
Father b = new Child();
}
}
3. 继承:向上转型向下转型
package model2.unit2;
public class Java08 {
public void m(Car c) {
Audi a = (Audi) c;
}
public static Car m2() {
return null;
}
public static void main(String[] args) {
double e = 2;
double i = e;
Car x = m2();
// 继承体系中的类型转换
// 向上转型:子类型转换为父类型:可以
// 向下转型:父类型转换为子类型:强制类型转换
Car c = new Audi();
Audi d = (Audi) c;
}
}
// 父类
abstract class Car {
abstract void driver();
}
// 子类
class Audi extends Car {
@Override
void driver() {
System.out.println("驾驶奥迪");
}
void m1() {
System.out.println("奥迪汽车独有的功能");
}
public static void main(String[] args) {
// 继承中:子类型转换为父类型
Audi a = new Audi();
Car b = a;
// 继承中:父类型转换为子类型、强制类型转换
Car c = new Audi();
Audi d = (Audi) c;
}
}
class Benz extends Car {
@Override
void driver() {
System.out.println("驾驶奔驰");
}
void m2() {
System.out.println("奔驰汽车独有的功能");
}
public static void main(String[] args) {
Object c = new Benz();
Car c1 = new Audi();
c1.driver();
Audi c2 = (Audi) c1;
c2.m1(); // 如果调用子类自己的方法、需要转换为子类型才可以调用。
}
}
4. 继承:instanceof
package model2.unit3;
public class Java01 {
public static void main(String[] args) {
// 继承中一个运算符:判断对象是否是某一个类的类型
Car car = new Benz();
if (car instanceof Audi) {
System.out.println("奥迪");
Audi a = (Audi) car;
}
if (car instanceof Benz) {
System.out.println("奔驰");
Benz b = (Benz) car;
}
}
}
5. 关键字:可见性
package model2.unit2;
public class Java01 {
public static void main(String[] args) {
// 可见性修饰符:4个范围3个关键字
// 私有的 private 只有当前类内部
// 默认的 当前类 + 本包
// 保护的 protected 当前类 + 本包 + 外包子类
// 公共的 public 所有
}
}
6. 关键字:final
package model2.unit2;
public class Java02 {
public static void main(String[] args) {
// final关键字:3种用法
// final修饰变量:表示常量、不能被修改的。
// final修饰类:不能被继承。
// final修饰方法:不能被覆盖。
}
}
7. 关键字:this和super
package model2.unit2;
public class Java03 {
String name;
int age;
public Java03(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Java03{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Java03 a = new Java03("张三", 30); // this表示a
System.out.println(a);
Java03 b = new Java03("李四", 40); // this表示b
// this关键字和super关键字
// this关键字:表示当前类的对象。可以用于本类构造方法之间的调用。
// super关键字:表示父类的引用。可以用于本类构造方法调用父类构造方法。
}
}
8. 默认:构造方法
package model2.unit2;
public class Java04 {
// 如果不编写构造方法、系统会默认提供一个公共无参的构造方法。
// 如果有构造方法、系统则不会提供。
public static void main(String[] args) {
Java04 a = new Java04();
System.out.println(a);
}
}
9. 默认:成员变量值
package model2.unit2;
public class Java05 {
int a;
double b;
boolean c;
int[] d;
Person e;
void m() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);
}
public static void main(String[] args) {
// 成员变量:默认值
// 整数默认0
// 浮点默认0.0
// 布尔默认false
// 类类型默认null
// 成员变量系统会默认赋初始值。
// 局部变量必须我们赋值之后才可以使用。
Java05 t = new Java05();
t.m();
}
}
10. 默认:Object类
package model2.unit2;
public class Java06 extends Object {
// 如果一个类没有直接继承某个父类、系统将默认让这个类继承Object类。
// Object类是java的顶级父类、所有类都直接或间接的继承这个类。
}
11. hashCode方法
package unit1;
public class Java06 {
public static void main(String[] args) {
// Member member = new Member();
// member.setName("张三");
// Object类:toString方法、hashcode方法
// toString方法的原理:包名.类名@哈希地址
// unit1.Member@1b6d3586
// System.out.println(member);
// System.out.println(member.toString());
// hashCode是获取哈希码(散列码)int整数、确定该对象在哈希表中的索引位置
// 注意:hashCode是本地方法(c/c++语言)
// 硬件层(c语言)、操作系统层(c/c++)、应用层(java)
// 被native关键字修饰的方法叫做本地方法
// java本地方法 -> 底层c/c++方法 -> 内存
// public native int hashCode();
Member member = new Member();
int i = member.hashCode();
System.out.println(i);
Member member2 = new Member();
int i2 = member2.hashCode();
System.out.println(i2);
// 线程启动原理也是本地方法:start() -> start0() -> private native void start0();
// Thread thread = new Thread();
// thread.start();// 启动线程
}
}
class Member extends Object {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
'}';
}
}
12. equals源码解析
package unit2;
public class Java17 extends Object {
public static void main(String[] args) {
// equals()方法的底层原理源码
// equals()是Object类中的方法
// 原理:默认比较的是两个对象的地址
// public boolean equals(Object obj) {
// return (this == obj);
// }
// 字符串中的equals方法
// 当前字符串的char[]和比较的字符串的char[]各个下标对应的字符逐个比较
// 如果有一个字符不相等返回false、否则返回true
// public boolean equals(Object anObject) {
// if (this == anObject) {
// return true;
// }
// if (anObject instanceof String) {
// String anotherString = (String)anObject;
// int n = value.length;
// if (n == anotherString.value.length) {
// char v1[] = value;
// char v2[] = anotherString.value;
// int i = 0;
// while (n-- != 0) {
// if (v1[i] != v2[i])
// return false;
// i++;
// }
// return true;
// }
// }
// return false;
// }
System.out.println("abc".equals("abc"));
// 引用类型比较相等必须使用equals方法、java的类已经实现equals方法
// 自定义类需要自己实现equals方法
}
}
13. toString源码解析
package unit2;
public class Java18 {
public static void main(String[] args) {
// toString方法底层原理源码
// toString方法是Object类中的方法
T t = new T();
t.setName("张三");
// public String toString() {
// return getClass().getName() + "@" + Integer.toHexString(hashCode());
// }
// hashCode()方法返回对象的哈希值int整数
// 包名.类名@Integer.toHexString(hashCode())
// 包名.类名@hashCode的16进制字符串
// 包名.类名@对象的内存地址
// 自定义类需要重写toString方法、打印对象的内部信息、而不是打印默认的地址
// unit2.T@1b6d3586
System.out.println(t);
System.out.println(t.toString());
System.out.println(t.hashCode());
System.out.println(Integer.toHexString(t.hashCode()));
// Integer.toHexString功能:10进制转换为16进制的字符串形式
// 10进制:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
// 16进制:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
// System.out.println(Integer.toHexString(13));
}
}
class T {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "名字是" + this.name;
}
}
(3)接口
1. 接口概念
package model2.unit3;
// 接口概念:被interface修饰的叫做接口。
// 成员变量概念:接口中所有变量默认被public static final修饰。
// 成员方法概念:接口中所有方法默认被public abstract修饰。
// 接口中没有构造方法、也不能创建对象。作用:设计工具。
public interface Person {
String name = "张三";
void m();
}
2. 接口的引用
package model2.unit3;
public interface Car {
void driver();
}
class Audi implements Car {
@Override
public void driver() {
System.out.println("驾驶奥迪汽车");
}
public static void main(String[] args) {
// (1)类名 变量 = new 类的构造方法:当前类的对象
// Audi a = new Audi();
// a.driver();
// (2)父类 变量 = new 子类的构造方法:父类的子类的对象
// Car b = new Audi();
// b.driver();
// (3)接口 变量 = new 实现类的构造方法:接口的实现类的对象
Car c = new Audi();
c.driver();
}
}
class Benz implements Car {
@Override
public void driver() {
// 实现方法
}
}
3. 接口新特性
package unit3;
public class Java27 {
public static void main(String[] args) {
K.m1();
P p = new P();
p.m2();
}
}
interface K {
static void m1(){
System.out.println(100);
}
default void m2(){
System.out.println(200);
}
}
class P implements K {
@Override
public void m2() {
System.out.println(300);
}
}
4. 泛型接口
package unit4;
import java.util.ArrayList;
import java.util.List;
public class Java36 {
public static void main(String[] args) {
// 泛型类
// 使用泛型参数编译器可以对泛型参数进行检测。类似与方法传参。
// 泛型方式:泛型类、泛型接口、泛型方法
N<String> n = new M<>();
System.out.println(n.m("泛型"));
Com<Emp> c1 = new Com();
Com<Mem> c2 = new Com();
}
}
class Com<T> {
List<T> list = new ArrayList<>();
}
class Mem {
}
class Emp {
}
// 泛型类的定义:使用类的过程中可以传递参数到类的内部
// 接口<泛型>/类<泛型>
interface N<T extends Object> {
T m(T a);
}
class M<T> implements N<T> {
@Override
public T m(T a) {
return a;
}
}
(4)枚举注解
1. 枚举类型
package unit4;
public class Java37 {
public static void main(String[] args) {
// 枚举类型
// 被enum关键字修饰叫做枚举、将一组值的有限集合存储起来的新的类型。
// 定义一个枚举类型的时候、java编译器会创建一个final类型的类继承Enum。
// Java语言的类型:类、接口、枚举、注解
}
}
// enums枚举包:枚举类型
// java中的枚举类型一般和数据库中的数据字典概念统一
// 性别枚举
enum Gender {
MALE("男"), FEMALE("女"), UNKNOW("未知");
private String genderName;
Gender(String genderName) {
this.genderName = genderName;
}
public String getGenderName() {
return genderName;
}
public void setGenderName(String genderName) {
this.genderName = genderName;
}
public static void main(String[] args) {
System.out.println(Gender.MALE.genderName);
System.out.println(Gender.FEMALE.getGenderName());
}
}
class Person {
String name;
String gender;
public Person(String name, String gender) {
this.name = name;
this.gender = gender;
}
public static void main(String[] args) {
Person p1 = new Person("张三", Gender.MALE.getGenderName());
}
}
// 后台的返回类型:枚举类型
enum Result {
SUCCESS(200, "操作成功"),
ERROR(500, "操作失败");
int code;
String message;
Result(int code, String message) {
this.code = code;
this.message = message;
}
public static void main(String[] args) {
System.out.println(Result.SUCCESS.message);
System.out.println(Result.ERROR.message);
}
}
2. 枚举使用
package unit4;
public class Java38 {
public static void main(String[] args) {
// 前台发送1,2
System.out.println(E.getName(1));
System.out.println(E.getName(2));
}
}
enum E {
OPTION1(1, "男"),
OPTION2(2, "女");
int value;
String name;
E(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
// 枚举的具体使用:
public static String getName(int value) {
for (E e : E.values()) {
if (e.getValue() == value) {
return e.getName();
}
}
return null;
}
}
3. 注解类型
package model2.unit4;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// @Target是注解的元注解之一、表示注解定义的目标位置
//ElementType.TYPE //类、接口和枚举上
//ElementType.FIELD //字段
//ElementType.METHOD //方法
@Target(ElementType.TYPE)
public @interface F {
String value();
int type();
}
4. 注解使用
package model2.unit4;
// 注解的使用
@F(value="", type=1)
public class G {
}
// 注解概念:被@interface修饰叫做注解。
// @Target 控制注解的范围位置的
// @Target(ElementType.TYPE) 类
// @Target(ElementType.FIELD) 成员变量
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface H {
String value();
int type();
}
package model2.unit4;
public class K {
int a;
@H(value = "", type = 2)
void m(){
}
}
(5)面向对象思想
1. 封装继承多态
package model2.unit5;
public class Java01 {
public static void main(String[] args) {
// Java语言是一个面向对象的语言:一切皆对象。
// 面向对象语言的三个特征:封装、继承、多态
// 封装:类把相关的变量和方法封装到类的内部。
// 好处:首先关注类的本身、然后再关注类的成员。
// 继承:子类通过extends关键字继承父类、父类有的子类都有。
// 好处:父类设计定义标准、子类实现标准。用户针对父类标准写代码就可以。
// 多态:
// 类内部多态:又叫做重载。在一个类中如果有多个方法的方法名相同参数不同。
// 举例:构造方法
// 好处:相同功能的方法给用户提供多钟选择。
// 继承中多态:又叫做覆写。
// 举例:toString方法
// 在父类和子类中、如果有2个方法的定义完全相同、自动执行子类的方法。
}
}
2. 关键字分析
package model2.unit6;
// (1)final不能修饰抽象类
// 抽象类:为了继承。
// final关键字:不能被继承。
public abstract class A {
// (2)private、final、static不能修饰抽象方法
// 抽象方法:子类实现。
// private关键字:只有当前类可见。
// final关键字:不能被覆写。
// static关键字:属于类。
abstract void m();
}
3. 单例模式
package unit3;
public class Java24 {
public static void main(String[] args) {
S s1 = S.getS();
S s2 = S.getS();
System.out.println(s1 == s2);
}
}
class S {
static S s;
private S(){
}
public synchronized static S getS(){
if (s == null) {
s = new S();
}
return s;
}
}
4. 工厂模式
package unit3;
public class Java25 {
public static void main(String[] args) {
Car car1 = CarFactory.getCar(2);
car1.driver();
}
}
interface Car {
void driver();
}
class Audi implements Car {
@Override
public void driver() {
System.out.println("奥迪实现驾驶");
}
}
class Benz implements Car {
@Override
public void driver() {
System.out.println("奔驰实现驾驶");
}
}
class CarFactory {
public static Car getCar(int i) {
if (i == 1) {
return new Audi();
} else if (i == 2) {
return new Benz();
} else {
return null;
}
}
}
5. 代理模式
package unit3;
public class Java26 {
public static void main(String[] args) {
E e = new F();
E proxy = new MyProxy(e);
proxy.m1("");
proxy.m2("");
}
}
interface E {
void m1(String s);
void m2(String s);
}
class MyProxy implements E {
E e;
public MyProxy(E e) {
this.e = e;
}
@Override
public void m1(String s) {
System.out.println("判断角色");
System.out.println("json转换java");
e.m1("a");
System.out.println("日志功能");
}
@Override
public void m2(String s) {
System.out.println("判断角色");
System.out.println("json转换java");
e.m2("b");
System.out.println("日志功能");
}
}
class F implements E {
@Override
public void m1(String s) {
System.out.println("实现添加功能");
}
@Override
public void m2(String s) {
System.out.println("实现修改功能");
}
}