一、static关键字
理解:
回顾以往类:
class Circle{
private double radius;
public Circle(double radius){
this.radius=radius;
}
public double findArea(){
return Math.PI*radius*radius;
}
}
//创建两个Circle对象
Circle c1=new Circle(2.0); //c1.radius=2.0
Circle c2=new Circle(3.0); //c2.radius=3.0
Circle类中的变量radius是一个实例变量(instance variable),它属于类的每一个对象,c1中的radius变化不会影响c2的radius,反之亦然。
所以static关键字的使用,可以使成员变量被该类下的所有实例c1、c2......共享。 静态变量(类变量)。
同样,对于类中的方法,有些可能不需要创建对象来调用该方法,此时我们也可以用static修饰该方法。 静态方法(类方法)。类名.静态方法。
- 随着类的加载而加载;
- 静态方法内不可以调用非静态的属性或方法。
- 非静态方法内都可以调用。
- 如果在类A中定义了静态方法,类A以外的类则不能创建A的对象来调用该静态方法。只能通过 ‘类名.静态方法’ 来调用。
二、设计模式
经典的设计模式有23种。
2.1 单例(Singleton) 设计模式
类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
2.2 单例模式实现 (掌握)
1、饿汉式:
/**
* ClassName:SingleTest
* Package: Exercise01
* Description:
*
* 单例设计模式设计实现1:饿汉式
*
* @Author Joan Jia
* @Create 2024/5/13 10:59
* @Version 1.0
*/
public class SingleTest {
public static void main(String[] args) {
/*
//此时这就不是单例模式了,因为有两个实例对象。
Single single1=new Single();
Single single2=new Single();
*/
Single single1=Single.getInstance();
Single single2=Single.getInstance();//两者指向的是同一个实例对象。
}
}
//第一种实现方式:饿汉式
class Single{
//1、将类的构造器私有化private。这样在类外部就不能new该类的对象了。
private Single(){
}
//2、在类的内部创建当前类的实例
//4、此属性也需声明为static
private static Single single=new Single();
/*
因为在类外部不能创建对象实例了,所以可以提供一个方法供外部调用,
但由于外部类中不能new该类的对象,那就只能通过类名直接调用静态方法的方式。
*/
//3、使用getXXX()方法获取当前类的实例,必须声明为static
public static Single getInstance(){
return single;
}
}
2、懒汉式
//第二种方式:懒汉式
class GirlFriend{
//1、将类的构造器私有化private。
private GirlFriend(){
}
//2、在类的内部创建当前类的实例
//4、此属性也需声明为static
private static GirlFriend girlFriend=null;
//3、使用getXXX()方法获取当前类的实例,如果为创建对象,则在方法内部创建
public static GirlFriend getInstance(){
if(girlFriend==null){
girlFriend=new GirlFriend();
}
return girlFriend;
}
}
2.3 饿汉式 VS懒汉式
饿汉式:
-
特点:立即加载,即在使用类的时候已经将对象创建完毕。
-
优点:实现起来
简单
;没有多线程安全问题。 -
缺点:当类被加载的时候,会初始化static的实例,静态变量被创建并分配内存空间,从这以后,这个static的实例便一直占着这块内存,直到类被卸载时,静态变量被摧毁,并释放所占有的内存。因此在某些特定条件下会
耗费内存
。
懒汉式:
-
特点:
延迟加载
,即在调用静态方法时实例才被创建。 -
优点:实现起来比较简单;当类被加载的时候,static的实例未被创建并分配内存空间,当静态方法第一次被调用时,初始化实例变量,并分配内存,因此在某些特定条件下会
节约内存
。 -
缺点:在多线程环境中,这种实现方法是完全错误的,
线程不安全
,根本不能保证单例的唯一性。 -
说明:在多线程章节,会将懒汉式改造成线程安全的模式。
三、final关键字
final:最终的,不可更改的
final修饰类:该类不能被继承 ;
final修饰方法:这个方法不能被子类重写;
final修饰变量(成员变量/局部变量):一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。
四、抽象类和抽象方法
抽象类、抽象方法:用abstract修饰。
[权限修饰符] abstract class 类名{
}
[权限修饰符] abstract class 类名 extends 父类{
}
[其他修饰符] abstract 返回值类型 方法名([形参列表]);//抽象方法没有实体。
包含抽象方法的类必须是抽象类。
抽象类不能创建对象 。
子类继承抽象类,重写其中的抽象方法,也叫做实现。
子类必须实现其抽象父类中的所有抽象方法。否则,除非该子类是抽象类。
五、接口
接口:
[修饰符] interface 接口名{
//接口的成员列表:
// 公共的静态常量
// 公共的抽象方法
// 公共的默认方法(JDK1.8以上)
// 公共的静态方法(JDK1.8以上)
// 私有方法(JDK1.9以上)
}
1、多实现:一个类可以实现多个接口。 同时,一个类可以继承一个类并实现多个接口。
2、接口不能创建对象,类与接口是实现implements 关系,类实现接口。所以接口中的方法需要其实现类的对象来调用。
3、多继承:一个接口能继承一个或多个接口。方法签名相同的抽象方法只需要实现一次。
4、接口与实现类对象构成多态引用。接口类型的变量调用方法,最终执行的是你new的实现类对象实现的方法体。
package com.atguigu.interfacetype;
public class Mouse implements USB3 {
@Override
public void out() {
System.out.println("发送脉冲信号");
}
@Override
public void in() {
System.out.println("不接收信号");
}
}
package com.atguigu.interfacetype;
public class KeyBoard implements USB3{
@Override
public void in() {
System.out.println("不接收信号");
}
@Override
public void out() {
System.out.println("发送按键信号");
}
}
package com.atguigu.interfacetype;
//测试类
public class TestComputer {
public static void main(String[] args) {
Computer computer = new Computer();
USB3 usb = new Mouse();//执行的是Mouse实现类中的方法。
computer.setUsb(usb);//理解为电脑连接接口usb
usb.start();
usb.out();
usb.in();
usb.stop();
System.out.println("--------------------------");
usb = new KeyBoard();
computer.setUsb(usb);
usb.start();
usb.out();
usb.in();
usb.stop();
System.out.println("--------------------------");
usb = new MobileHDD();
computer.setUsb(usb);
usb.start();
usb.out();
usb.in();
usb.stop();
}
}
接口与抽象类的对比:
六、注解
1、生成文档相关注解
2、在编译时进行格式检查(JDK内置的三个基本注解)
@Override
: 限定重写父类方法,该注解只能用于方法。【Ctrl+o】
@Deprecated
: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择。会标识一个横线
@SuppressWarnings
: 抑制编译器警告
3、 跟踪代码依赖性,实现替代配置文件功能
4、框架=注解+反射+设计模式
我们在开发中可以自定义注解,格式如下:
目前先不学了......用到了在学
七、包装类
使基本数据类型具备类的特征。
因为有的方法中只能传入引用数据类型。例如:
//情况1:方法形参
Object类的equals(Object obj)//java规定只能传入引用数据类型//情况2:方法形参
ArrayList类的add(Object obj)
//没有如下的方法:
add(int number)
add(double d)
add(boolean b)//情况3:泛型
Set<T>
List<T>
Cllection<T>
Map<K,V>
1、包装类
public static void main(String[] args){
int num = 520;
Integer obj = new Integer(520);}
2、包装类和基本数据类型的转换
2.1 装箱
把基本数据类型转为包装类对象 。
转为包装类的对象,是为了使用专门为对象设计的API和特性 ???