【学习笔记之JavaSE】-4.3面向对象

本文深入探讨Java中的关键概念,包括static、final、抽象类、接口、内部类等,解析其使用场景与机制,如单例模式、模板方法设计模式、代理模式等,帮助读者掌握Java编程的核心要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 关键字:static

why:
1.原本只有通过new关键字产生出对象,这时系统才会分配内存空间给对象, 其方法才可以供外部调用。想不用创建对象,直接类调用
2.无论创建多少对象,想让某些特定的数据在内存空间里只有一份

static:静态的,static可以用来修饰:属性、方法、代码块、内部类

1.1 static修饰属性

即静态变量(或类变量)
类的多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。而非静态属性不会。

说明:

  1. 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
  2. 静态变量的加载要早于对象的创建。
  3. 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。

应用场合:

  1. 属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
  2. 类中的常量也常常声明为static

1.2 static修饰方法

即静态方法
说明:

  1. 随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
  2. 静态方法中,只能调用静态的方法或属性;
    而非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
  3. 在静态的方法内,不能使用this关键字、super关键字
调用权限类变量实例变量类方法实例方法
yesnoyesno
对象yesyesyesyes

PS:主要从生命周期考虑,static修饰成员随类加载而加载,早于实例对象的创建。故可不创建对象,直接被类调用

应用场景:

  1. 操作静态属性的方法,通常设置为static的
  2. 工具类中的方法,习惯上声明为static的。 比如:Math、Arrays、Collections

内存解析
在这里插入图片描述

1.3单例设计模式

采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例
思想:构造器的访问权限设置为private --》调用该类的某个静态方法返回内部创建的对象–》指向类内部产生的该类对象的变量也必须定义成静态的

//饿汉式 坏处:对象加载时间过长。  好处:饿汉式是线程安全的
class Bank{
	//1.私有化类的构造器
	private Bank(){	
	}
	//2.内部创建类的对象
	//4.要求此对象也必须声明为静态的
	private static Bank instance = new Bank();
	//3.提供公共的静态的方法,返回类的对象
	public static Bank getInstance(){
		return instance;
	}
}
//懒汉式 好处:延迟对象的创建 
class Order{
	//1.私有化类的构造器
	private Order(){	
	}
	//2.声明当前类对象,没有初始化
	//4.此对象也必须声明为static的
	private static Order instance = null;
	//3.声明public、static的返回当前类对象的方法
	public static Order getInstance(){
	   if(instance==null){
		 synchronized(Order.class){ //静态方法内得用类作 锁
			if(instance == null){	
				instance = new Order();	
			}
		 }
	   }
	   return instance;
	}
	}

2 main()方法

public static void main(String[] args) {

}

使用说明:
1.main()方法作为程序的入口(虚拟机要调用,故权限为public)
2.main()方法是静态方法(故虚拟机执行main()方法时不必创建对象)
3.main()方法可以作为我们与控制台交互的方式(String类型的数组参数,保存执行Java命令时传递给所运行的类的参数)
传参方式1:java 字节码文件名 参数1 参数2 …
传参方式2:Run->Edit Configuration:“1” "2"选择传参的位置 "3"为传入的字符串参数,空格隔开
在这里插入图片描述

3.代码块

代码块如果有修饰的话,只能使用static.即静态代码块

VS静态代码块非静态代码块
作用初始化类的信息可对对象的属性等进行初始化
执行随类加载而执行,且只执行一次随对象的创建而执行,每创建一次就执行一次
执行顺序由父及子静态先行,声明先后
调用静态的属性、静态的方法静态and非静态的属性方法
  • 对属性可以赋值的位置及执行先后顺序:
    ①默认初始化
    ②显式初始化/⑤在代码块中赋值
    ③构造器中初始化
    ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值

4.关键字:final

final:最终的

  1. final可以用来修饰的结构:类、方法、变量
  2. final 用来修饰一个类:此类不能被其他类所继承。比如:String类、System类、StringBuffer类
  3. final 用来修饰方法:表明此方法不可被重写。比如:Object类中getClass();
  4. final 用来修饰变量:此时的"变量"就称为是一个常量
    ①final修饰属性:可赋值的位置有:显式初始化、代码块中初始化、构造器中初始化,否则不能用
    ②final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
  • static final 用来修饰属性:全局常量

5.抽象类与抽象方法

抽象方法:声明一个方法但不提供实现,该方法的实现由子类提供。
抽象类:有时将一个父类设计得非常抽象(时常含抽象方法),以至于它没有具体的实例。

5.1关键字:abstract

abstract:抽象的

  1. abstract可以用来修饰的结构:类、方法
  2. abstract修饰类:抽象类
    格式:abstract class A{ }
    ①此类不能实例化
    ②抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
    ③开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
  3. abstract修饰方法:抽象方法
    格式:权限修饰 abstract 方法名();
    ①抽象方法只有方法的声明,没有方法体
    ②包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
    ③若子类重写了父类中的所有的抽象方法后,此子类方可实例化;否则此子类也是一个抽象类,需要使用abstract修饰

PS:abstract不能用来修饰(从是否可以被重写的角度考虑:属性、构造器、私有方法、静态方法、final的方法、final的类(不能继承

5.2模板方法设计模式

在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。

//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {
	public static void main(String[] args) {
		BankTemplateMethod btm = new DrawMoney();
		btm.process();
		BankTemplateMethod btm2 = new ManageMoney();
		btm2.process();
	}
}
abstract class BankTemplateMethod {
	// 具体方法
	public void takeNumber() {
		System.out.println("取号排队");
	}
	public abstract void transact(); // 办理具体的业务 //钩子方法
	public void evaluate() {
		System.out.println("反馈评分");
	}
	// 模板方法,把基本操作组合到一起,子类一般不能重写
	public final void process() {
		this.takeNumber();
		this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
		this.evaluate();
	}
}
class DrawMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("我要取款!!!");
	}
}
class ManageMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("我要理财!我这里有2000万美元!!");
	}
}

6.接口(interface)

接口,实际上可以看做是一种规范。接口实现则是 "能不能"的关系,而继承是一个"是不是"的关系

  1. Java中,接口和类是并列的两个结构
  2. 接口中无构造器!意味着接口不可以实例化
  3. JDK7及以前:只能定义全局常量和抽象方法
    ①全局常量:默认是由public static final修饰的
    ②抽象方法:默认是由public abstract修饰的
  4. JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(这default不能缺省
    ①接口中定义的静态方法,只能通过接口来调用。
    ②接口中的默认方法:实现类的对象调用,若实现类重写了该方法,则调用重写
    实现类实现多个接口,而这多个接口中定义了同名同参数的默认方法。若实现类没重写则接口冲突
    子类(实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,类优先原则。但声明同名成员变量则需指定调用(同方法指定见程序
interface Filial {// 孝顺的
	default void help() {
		System.out.println("老妈,我来救你了");
	}
}
interface Spoony {// 痴情的
	default void help() {
		System.out.println("媳妇,别怕,我来了");
	}
}
class Father{
	public void help(){
		System.out.println("儿子,就我媳妇!");
	}
}
class Man extends Father implements Filial, Spoony {
	@Override
	public void help() {
		System.out.println("我该就谁呢?");
		
	}
    public void Choice{
    	help(); //重写的方法
    	super.help(); //调用父类方法
		Filial.super.help(); //调用接口的默认方法
		Spoony.super.help(); //调用接口的默认方法
    }
}
  1. Java开发中,接口通过让类去实现(implements)的方式来使用. 具体使用体现多态性
    ①如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化;否则此实现类仍为一个抽象类
  2. Java类可以实现多个接口 —>弥补了Java单继承性的局限性
    格式:class AA extends BB implements CC,DD,EE{ }
  3. 接口与接口之间可以继承,而且可以多继承

在这里插入图片描述

public class USBTest {
	public static void main(String[] args) {
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		com.transferData(flash);
		//2. 创建了接口的非匿名实现类的匿名对象
		com.transferData(new Printer());
		//3. 创建了接口的匿名实现类的非匿名对象
		USB phone = new USB(){
			@Override
			public void start() {
				System.out.println("手机开始工作");
			}
			@Override
			public void stop() {
				System.out.println("手机结束工作");
			}
		};
		com.transferData(phone);
		//4. 创建了接口的匿名实现类的匿名对象
		com.transferData(new USB(){
			@Override
			public void start() {
				System.out.println("mp3开始工作");
			}
			@Override
			public void stop() {
				System.out.println("mp3结束工作");
			}
		});
	}
}

class Computer{
	public void transferData(USB usb){//USB usb = new Flash();
		usb.start();
		System.out.println("具体传输数据的细节");
		usb.stop();
	}
}

interface USB{
	//常量:定义了长、宽、最大最小的传输速度等
	void start();
	void stop();	
}

class Flash implements USB{
	@Override
	public void start() {
		System.out.println("U盘开启工作");
	}
	@Override
	public void stop() {
		System.out.println("U盘结束工作");
	}
}

class Printer implements USB{
	@Override
	public void start() {
		System.out.println("打印机开启工作");
	}
	@Override
	public void stop() {
		System.out.println("打印机结束工作");
	}
}

6.1代理模式

代理设计就是为其它对象提供一种代理以控制对这个对象的访问。
应用场景:

  1. 安全代理:屏蔽对真实角色的直接访问。
  2. 远程代理:通过代理类处理远程方法调用(RMI)
  3. 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
public class NetWorkTest {
	public static void main(String[] args) {
		Server server = new Server();
//		server.browse();
		ProxyServer proxyServer = new ProxyServer(server);
		proxyServer.browse();
	}
}

interface NetWork{
	public void browse();
}
//被代理类
class Server implements NetWork{
	@Override
	public void browse() {
		System.out.println("真实的服务器访问网络");
	}
}
//代理类
class ProxyServer implements NetWork{
	private NetWork work;
	public ProxyServer(NetWork work){
		this.work = work;
	}
	public void check(){
		System.out.println("联网之前的检查工作");
	}
	@Override
	public void browse() {
		check();
		work.browse();
	}
}

7.内部类

Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类

1.成员内部类(静态、非静态):具备类的所有特性,同时也具备成员的可被4种不同的权限修饰

  • 实例化成员内部类的对象
    ①静态的成员内部类:B.A a = new B.A();
    ②非静态的成员内部类:B b = new B(); B.A a = b.new A();

  • 在成员内部类中区分调用内外部类的同名结构
    ②非静态的成员内部类:
    this.属性方法 //调用内部类的
    B.this.属性方法 //调用外部类的

2.局部内部类(方法内、代码块内、构造器内)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空•物语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值