java-day14

1 内部类

1.1 概述
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。常用于接口多

在java中,允许一个类的定义为于另一个类的内部,前者称为内部类,后者称为外部类。

innerclass 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称

1.2 分类
变量 :
成员变量 : 成员内部类
静态变量 : 静态内部类
局部变量 : 局部内部类
形参和实参变量 : 匿名内部类

成员内部类 :
1 可以等同看做成员变量
2 成员内部类中不能有静态声明
3 成员内部类中可以直接访问外部类所有的属性

成员内部类

package com.demo.InnerClass;

public class _01_OuterClass {
	private static String s1 = "A";
	private String s2 = "B";
	// private,public,protected 都可以使用
	// 编译后的类名为 外部类类名$内部类类名
	// _01_OuterClass$InnerClass
	class InnerClass {
		// 不能有静态声明
		// static int x = 2;
		// public static void m1(){ }
		
		public void m2(){
			// 可以直接访问外部类的所有属性
			System.out.println(s1);	//A
			System.out.println(s2);//B
		}
	}
	
	public static void main(String[] args) {
		
		// 创建外部类对象
		_01_OuterClass oc = new _01_OuterClass();
		// 通过外部类对象去创建成员内部类对象
		InnerClass ic = oc.new InnerClass();
		ic.m2();

	}
	
}

1.4 静态内部类

静态内部类
1 可以看做静态变量
2 静态内部类中,不能直接访问成员数据,需要有对象才行
3 静态内部类中可以声明所有东西

package com.demo.InnerClass;

public class _02_OuterClass {
	private static String s1 = "A";
	private String s2 = "B";
	
	//静态内部类
	private static class InnerClass{
		public static void m1() {
			System.out.println(s1);
			//Cannot make a static reference to the non-static field s2
			//不能直接访问成员属性
//			System.out.println(s2);
			
			//成员属性需要对象调用
			_02_OuterClass s = new _02_OuterClass();
			System.out.println(s.s2);
		}
		public void m2() {
			System.out.println(s1);
			
			//在成员方法中也不能直接方法问成员属性
//			System.out.println(s2);
		}
	}
	public static void main(String[] args) {	
		
		//外部类.内部类.静态
		_02_OuterClass.InnerClass.m1();
		//访问当前类的静态属性的时候,类名可以省略
		InnerClass.m1();
		InnerClass ic = new _02_OuterClass.InnerClass();
		InnerClass ic1 = new InnerClass();
		ic.m2(); 
	}

}

1.5 局部内部类
局部内部类等同于局部变量

注意 : 局部内部类 在访问外部方法中的局部变量的时候需要加final修饰(1.8之前),从1.8开始 final可以省略

局部内部类中,不能有静态声明

如果是成员方法中的局部内部类,可以访问外部类中所有 的属性

如果是静态方法中局部内部类, 不可以直接访问外部类的成员属性

package com.demo.InnerClass;

public class _03_OuterClass {
	private static String s1 = "A";
	private String s2 = "B";

	public static void main(String[] args) {
		_03_OuterClass oc = new _03_OuterClass();
		// oc.m1();
		m2();
	}

	// 静态方法
	public static void m2() {
		int i = 2;
		class InnerClass {
			// 不能有静态声明
			// public static void m3(){}
			public void m3() {
				System.out.println(s1);//A
				// 因为是静态方法中 的内部类,所以不能直接访问外部类的成员属性,需要创建对象
				// System.out.println(s2);
				_03_OuterClass a = new _03_OuterClass();
				System.out.println(a.s2);//B
				System.out.println(new _03_OuterClass().s2);//B
				// 1.8开始,访问局部变量的时候,可以不加final修饰,但是 值依然不能更改
				System.out.println(i);//2
			}
		}
		
		// 调用
		InnerClass ic = new InnerClass();
		ic.m3();
	}

	// 成员方法
	public void m1() {
		final int i = 10;
		// 不能使用权限修饰符
		class InnerClass {
			// public static void m3(){}
			public void m4() {
				System.out.println(s1);
				// 因为是成员方法中的局部内部类,所以可以直接访问外部类中的所有属性
				System.out.println(s2);
				// 1.8开始,访问局部变量的时候,可以不加final修饰,但是 值依然不能更改
				System.out.println(i);
			}
		}
		// 调用,只能在方法中调用
		InnerClass ic = new InnerClass();
		ic.m4();
	}
}

1.6 匿名内部类

匿名内部类 : 指在方法调用时,实参需要传入某个接口对象的时候,不传入对象,传入一个匿名的实现类

如果方法定义形成 一般是个接口,那么调用的时候,就需要传入其实现类的对象

但是可以不实现这个接口,不传递实现类对象,传递一个匿名内部类,这个类,没有名字,不能复用

默认的匿名内部类类名 : 外部类类名$1 一次类推

那么既然是没有名字的类,那么我们自然无法创建对象,但是传入匿名内部类的 时候回自动创建一个对象

package com.demo.InnerClass;

/**匿名内部类多用于接口*/
public class _04_OuterClass {

	public static void main(String[] args) {
		ICustomerService cs = new CustomerServiceImpl();
		m1(cs);//已退出登陆

		// 匿名内部类写法
		// 少定义一个类
		// 但是无法重复使用
		m1(new ICustomerService() {
			int i = 2;
			@Override
			public void logout() {
				System.out.println("已退出登陆" + this);//已退出登陆com.demo.InnerClass._04_OuterClass$1@15db9742
			}
		});
		
		m2(new A(){
			// 等于是创建了一个A的子类,并覆写了m3方法
			public void m3(){
				System.out.println("sssssss");
				super.m3();//===
			}
		});
	}

	public static void m1(ICustomerService cs) {
		cs.logout();
	}
	public static void m2(A a) {
		a.m3();
	}
}

interface ICustomerService {
	public void logout();
}

class CustomerServiceImpl implements ICustomerService {
	@Override
	public void logout() {
		System.out.println("已退出登陆");
	}
}
class A{
	public void m3(){
		System.out.println("===");
	}
}

2. 设计模式

2.1 概述
代表了最佳的实现方式,是一些有经验的开发人员,通过开发中总结出来的一些经验和错误,用来解决一系列问题

是前辈们对代码开发经验的总结,不是特定的语法结构,而是一套用来提供可复用性,可维护性,可读性,健壮性,安全性的解决方案

就是在编码实践中发现很多的编码方式经常会被用到,于是就总结出来 形成固定的结构
简单来说,世上本没有路,走的人多了,便有了路

如果开发中,用到了一些设计模式的话,就等于使用了他人总结的经验成果,可以避免很多问题

目前比较成熟的设计模式 有23种

2.2 单例模式
目的 : 让某个类只创建一个对象
在这里插入图片描述

单例模式 : 只让某个类创建一个对象

实现步骤 :
首先我们要控制创建对象的数量,就不能让用户决定创建和不创建,应该由我们去控制
构造方法是用来创建对象的,想要把创建对象的权利 控制在我们手中的话,那么就不能让用户直接访问我们的构造方法

1 构造方法私有化
我们已经把构造方法私有化了,就意味着用户创建不了对象了
那么这个时候,我们应该创建一个对象给用户,怎么给?
对外提供一个公共的静态方法,调用该方法就能返回一个对象。

2 创建一个公共的静态的方法用来返回当前类的对象,并且保证 只实例化一次
当调用处通过该方法获取对象的时候,先判断是否已经创建了对象,如果没有就创建一个并存储
如果已经创建 就直接返回该对象
所以 需要 一个存储对象的变量,这个变量必须是和类生命周期相关的
如果是一个局部变量的话,方法每次调用,都会重新初始化局部变量,所以 每次都会创建对象
如果是个成员变量,那么问题更严重,静态方法中不能直接操作成员变量
所以 只能是静态变量,并且这个变量要私有化不能被外部访问,外衣用户直接更改变量的值咋办?

3 创建一个私有化的静态变量,用于存储当前类的对象(变量的类型,是当前类类型)

注:采用静态,使程序每次new一个时产生对象地址始终一样的

根据对象不同的创建时机,分为两种情况:
1 懒汉模式 : 第一次获取对象的时候,再创建对象
2 饿汉模式 : 加载类的时候,就创建对象

package com.demo.Singleton;

/**
 * 懒汉设计模式:第一次获取对象的时候,再创建对象
 * */
public class _01_Singleton {
	//私有化构造方法
	private _01_Singleton() {}
	
	//私有化静态变量,用于存储当前对象
	private static _01_Singleton s;
	
	// 对外提供一个获取当前对象的方法
	public static _01_Singleton getInstance() {
		// 判断s是否为空,
		// 如果为空 说明没有创建过对象,就创建一个
		if (s == null) {
			s = new _01_Singleton();
		}
		// 不为空就说明创建过对象,就直接返回该对象
		return s;
	}


}
package com.demo.Singleton;

/**
 * 单例模式 : 只让某个类创建一个对象
 * 
 * 实现步骤 : 
 * 
 * 		首先我们要控制创建对象的数量,就不能让用户决定创建和不创建,应该由我们去控制
 * 
 * 		构造方法是用来创建对象的,想要把创建对象的权利 控制在我们手中的话,那么就不能让用户直接访问我们的构造方法
 * 
 * 		1 构造方法私有化
 * 				我们已经把构造方法私有化了,就意味着用户创建不了对象了
 * 				那么这个时候,我们应该创建一个对象给用户,怎么给?
 * 				对外提供一个公共的静态方法,调用该方法就能返回一个对象,
 * 		2 创建一个公共的静态的方法用来返回当前类的对象,并且保证 只实例化一次
 * 				当调用处通过该方法获取对象的时候,先判断是否已经创建了对象,如果没有就创建一个并存储
 * 				如果已经创建  就直接返回该对象
 * 				所以 需要 一个存储对象的变量,这个变量必须是和类生命周期相关的
 * 				如果是一个局部变量的话,方法每次调用,都会重新初始化局部变量,所以 每次都会创建对象
 * 				如果是个成员变量,那么问题更严重,静态方法中不能直接操作成员变量
 * 				所以 只能是静态变量,并且这个变量要私有化不能被外部访问,外衣用户直接更改变量的值咋办?
 * 		3 创建一个私有化的静态变量,用于存储当前类的对象(变量的类型,是当前类类型)
 * 
 *  根据对象不同的创建时机,分为两种情况
 *  		1 懒汉模式 : 第一次获取对象的时候,再创建对象
 *  		2 饿汉模式 : 加载类的时候,就创建对象
 *  
 *  
 *
 */
public class SglClient {
	public static void main(String[] args) {
		System.out.println(_01_Singleton.getInstance());
		System.out.println(_01_Singleton.getInstance());
		System.out.println(_01_Singleton.getInstance());
		System.out.println(_01_Singleton.getInstance());
		System.out.println("----------");
		System.out.println(_02_Singleton.getInstance());
		System.out.println(_02_Singleton.getInstance());
		System.out.println(_02_Singleton.getInstance());
		System.out.println(_02_Singleton.getInstance());
		/**
		 * 	com.demo.Singleton._01_Singleton@15db9742
			com.demo.Singleton._01_Singleton@15db9742
			com.demo.Singleton._01_Singleton@15db9742
			com.demo.Singleton._01_Singleton@15db9742
			----------
			com.demo.Singleton._02_Singleton@6d06d69c
			com.demo.Singleton._02_Singleton@6d06d69c
			com.demo.Singleton._02_Singleton@6d06d69c
			com.demo.Singleton._02_Singleton@6d06d69c

		 */
	}
}

2.3 工程模式
工厂模式 : 把创建对象的语句单独封装成一个工厂模式

这样 所有用到这个对象的地方,都去工厂中获取,把类之间强依赖关系变弱,灵活度更高
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.demo.Factory;

/**
 * 工厂模式 : 把创建对象的语句单独封装成一个工厂模式
 * 
 * 这样 所有用到这个对象的地方,都去工厂中获取,把类之间强依赖关系变弱,灵活度更高
 * 
 */
public class _01_Factory {

	public static void main(String[] args) {
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
//		fight(new ZhuanTou());
		
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());
//		fight(new RPG());		
		
		
		fight(WeaponFactory.getWeapon());
		fight(WeaponFactory.getWeapon());
		fight(WeaponFactory.getWeapon());
		fight(WeaponFactory.getWeapon());
		
		fight(new AK47());
		fight(new AK47());
	}

	public static void fight(Weapon w) {
		w.fireInTheHole();
	}
}

package com.demo.Factory;

public class AK47 implements Weapon{

	@Override
	public void fireInTheHole() {
		System.out.println("DADADADA~");
	}

}

package com.demo.Factory;

public class RPG implements Weapon{

	@Override
	public void fireInTheHole() {
		System.out.println("peng~");
	}

}

package com.demo.Factory;

public class Test {

	public static void main(String[] args) {
		String username = "root";
		String password = "123";
		login(username, password);
		
	}

	public static void login(String username,String password){
		System.out.println("登陆成功");
	}
}

package com.demo.Factory;
//Weapon 接口 里面有fireInTheHole方法
public interface Weapon {
	public void fireInTheHole();
}

package com.demo.Factory;

public class WeaponFactory {
	public static Weapon getWeapon() {
//		return new ZhuanTou();
		return new RPG();
	}
}

package com.demo.Factory;

public class ZhuanTou implements Weapon{

	@Override
	public void fireInTheHole() {
		System.out.println("PA~");
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值