object、内部类

一、内部类

1.1 定义

  • 定义在类的内部的类成为内部类
  • 能描述更多的关于对象的信息

1.2 分类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

二、成员内部类

2.1 定义

  • 定义在类的内部,和成员变量和成员方法位置一致
  • 成员内部类对象的创建要依赖外部类对象
  • 作用:存更多数据

2.2 基本使用

package com.qf.inner;

public class Demo01 {
	public static void main(String[] args) {
		// 创建内部类对象的方式
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		
		// 创建内部类对象
		Outer.Inner in = new Outer().new Inner();
		
		System.out.println(outer.name);
		
		System.out.println(in.name);
		
		inner.show();
		
		inner.getMethod();
		
	}
}

class Outer{
	// 属性
	String name = "外部类的name";
	int age = 22;
	private String addr = "外部类的地址";
	String[] names;
	
	// 内部类
	class Inner{
		String name = "内部类的name";
		
		public void show() {
			// 获取外部类的属性
			System.out.println("获取外部类私有属性addr" + addr);
			// 局部优先--就近原则
			System.out.println("不知道是谁的name" + name);
			// 指明调用外部类的name
			System.out.println("不知道是谁的name" + Outer.this.name);
		}
		
		public void getMethod() {
			// 调用外部类的方法
			haha();
		}
	}
	
	public void haha() {
		System.out.println("我是外部类的haha");
	}
}

class Computer{
	String brand;
	int price;
	
	// 处理器也是电脑的组成部分,但是处理器的属性和方法也很多,无法直接使用一个字符串描述完整,所以写成内部类
	class CPU{
		String brand;
		String type;
		int price;
		
		public void roastMeat() {
			System.out.println("处理器的温度在负荷打的时候很高,可以拿来烤肉...");
		}
	}
}

三、静态内部类

3.1 定义

  • 使用static修饰的成员内部类变成静态内部类
  • 静态内部类随着外部类的加载而加载,但是静态的内部类的内容需要被调用到的时候才能加载进去

3.2 静态内部类使用

package com.qf.inner;

public class Demo02 {
	public static void main(String[] args) throws ClassNotFoundException {
		// System.out.println(Out.In.class);
		Class.forName("com.qf.inner.Out$In");
		System.out.println("========================");
		//静态内部类创建对象
		Out.In in = new Out.In();
		in.showIn();
		in.staticIn();
		// 静态内部类的静态方法可以通过    外部类.内部类.方法名   调用
		Out.In.staticIn();
		
		// 静态内部类的静态属性可以通过 外部类.内部类.属性名  调用
		System.out.println(Out.In.infoIn);
		
		// 静态内部类调用外部类的静态属性和方法
		// Out.In.getOutInfo();
		in.getOutInfo();
	}
}


class Out{
	// 属性
	String name = "我是外部类的name";
	int age = 23;
	static String info =  "我是外部类Out的静态属性info";
	
	{
		System.out.println("wai部类动态代码块》》》》》》》》》》》》》》》》》》》》》》》》》");
	}
	
	static {
		System.out.println("wai部类的static代码块=================");
	}
	
	// 方法
	public void showOut() {
		System.out.println("我是外部类的非静态方法showOut");
	}
	
	public static void staticOut() {
		System.out.println("我是外部类的静态方法staticOut");
	}
	
	// 静态内部类
	static class In{
		// 属性
		String nameIn = "我是nei部类的name";
		int ageIn = 23;
		static String infoIn =  "我是nei部类In的静态属性infoIn";
		
		{
			System.out.println("内部类动态代码块》》》》》》》》》》》》》》》》》》》》》》》》》");
		}
		
		static {
			System.out.println("内部类的static代码块=================");
		}
		
		// 方法
		public void showIn() {
			System.out.println("我是nei部类的非静态方法showIn");
		}
		
		public static void staticIn() {
			System.out.println("我是nei部类的静态方法staticIn");
		}
		
		public void getOutInfo() {
			System.out.println("外部类的info:" + info);
			// 调用外部类的方法
			staticOut();
		}
		
		public void getOutNonStaticInfo() {
			// 无法调用外部类非静态的属性
			// System.out.println("外部类的name:" + name);
			// 无法调用外部类非静态的方法
			// showOut();
		}
	}
}

四、局部内部类

4.1 定义

  • 定义在方法内部的类成为局部内部类
  • 局部内部类在调用外部方法中的变量时候,变量需要使用final修饰
  • jdk1.8之后把这个设置成为默认

4.2 局部内部类使用

package com.qf.inner;

public class Demo03 {
	public static void main(String[] args) {
		// 局部变量num
		int num = 110;
		
		
		// 局部内部类
		class InnerClass{
			String name = "局部内部类的name";
			int i = 20;
			
			public void show() {
				System.out.println("局部内部类的name" + name);
				System.out.println("main方法中的局部变量num:" + num);
			}
		}
		
		// 注意创建对象的位置:需要在类的代码后面才行
		InnerClass ic = new InnerClass();
		ic.show();
		
		System.out.println("OVER!");
	}
}

五、匿名内部类

5.1 定义

  • 没有名字的内部类,写在方法内部
  • 创建对象、实现方法、调用方法于一体
  • 接口的new是使用了匿名内部类实现了接口,而不是new一个新对象

5.2 匿名内部类使用

package com.qf.inner;

public class Demo05 {
	public static void main(String[] args) {
		// 匿名内部类,创建对象、实现方法、调用方法与一体
		new RJ45() {
			@Override
			public void transfer() {
				System.out.println("我们使用的网线是千兆级别的...");
			}
		}.transfer();
		
		// 把创建的匿名内部类对象赋给一个引用
		RJ45 rj45 = new RJ45() {
			
			@Override
			public void transfer() {
				System.out.println("我们使用的网线是百兆级别的...");
			}
		};
		rj45.transfer();
	}
}
/**
 * 网线接口
 * 	提供数据传输的方法
 * @author Dushine2008
 *
 */
interface RJ45{
	void transfer();
}

六、接口回调

6.1 接口回调

package com.qf.inner;

public class Demo06 {

	public static void main(String[] args) {
		Worker worker = new Worker();
		Boss boss = new Boss(worker);
		boss.giveWork("挖坑埋自己");
	}

}

interface OnWorkFinishedListener{
	void workFinishedListener(String result);
}

/**
 * Boss类
 * @author Dushine2008
 *
 */
class Boss implements OnWorkFinishedListener{
	Worker worker;

	public Boss(Worker worker) {
		super();
		this.worker = worker;
	}

	@Override
	public void workFinishedListener(String result) {
		System.out.println("监听到工人的反馈:" + result);
	}
	
	// 分配工作
	public void giveWork(String workName) {
		worker.work(workName, this);
	}
	
}

/**
 * 工人类
 * 	完成工作
 * 	给与反馈
 * @author Dushine2008
 *
 */
class Worker{
	public void work(String workName,Boss boss) {
		System.out.println("工人接收到任务:" + workName);
		System.out.println("工作即将完成.....");
		boss.workFinishedListener(workName + "的工作完成....");
	}
}

6.2 使用匿名内部类实现接口回调

package com.qf.inner;

public class Demo07 {
	public static void main(String[] args) {
		User user = new User();
		// 调用对象的修改名字的方法,在匿名内部类中实现修改名字的方法
		user.setName("zhangsan", new OnNameChangedListener() {
			
			@Override
			public void nameChangedListener(String name) {
				System.out.println("正在努力修改名字..........");
				System.out.println("用户名修改成功,当前用户名:" + name);
			}
		});
	}
}

/**
 * 监听名字被修改的接口
 * @author Dushine2008
 *
 */
interface OnNameChangedListener{
	void nameChangedListener(String name);
}

/**
 * 用户类
 * 	提供了修改名字的方法
 * @author Dushine2008
 *
 */
class User{
	public void setName(String name,OnNameChangedListener onNameChangedListener) {
		onNameChangedListener.nameChangedListener(name);
	}
}

七、Object

7.1 定义

  • Object是java类层次结构中的顶层父类
  • 是所有类的超类,所有的类都直接或者间接继承Object
  • 所有的对象都有Object中的方法

7.2 getClass

  • 返回当前对象的类对象
package com.qf.obj;

public class Demo01 {
	public static void main(String[] args) {
		/**
		 * getClass
		 * 	返回当期对象所属的类对象
		 */
		String str = "abcdefg";
		Class<? extends String> clazz = str.getClass();
		System.out.println(clazz);
		
		String[] strs = {"",""};
		Class<? extends String[]> clazz1 = strs.getClass();
		System.out.println(clazz1);
		
		Integer[] arr = {11,22,33};
		System.out.println(arr.getClass());
	}
}

7.3 hashCode

  • 对象的哈希码值
  • 是经过地址换算出来的一个数字,可以看做是对象的唯一标识
package com.qf.obj;

public class Demo02 {
	public static void main(String[] args) {
		Stu s01 = new Stu("张三", 23);
		Stu s02 = new Stu("张三", 23);
		Stu s03 = new Stu("张三", 23);
		Stu s04 = new Stu("张三", 23);
		
		System.out.println(s01.hashCode());
		System.out.println(s02.hashCode());
		System.out.println(s03.hashCode());
		System.out.println(s04.hashCode());
		
		System.out.println(s01.hashCode());
		System.out.println(s02.hashCode());
		System.out.println(s03.hashCode());
		System.out.println(s04.hashCode());
		
	}
}

class Stu{
	// 属性
	String name;
	int age;
	
	public Stu() {
		super();
	}

	public Stu(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	// 方法
	public void show() {
		System.out.println(name + "===" + age);
	}
}

7.4 toString

  • 返回对象的字符串表示形式
  • 默认返回类型名称@十六进制字符串
    • p01.getClass().getName() + “@” + Integer.toHexString(p01.hashCode())
  • 建议所有子类重写此方法
package com.qf.obj;

public class Demo03 {
	public static void main(String[] args) {
		Person p01 = new Person("张三", 23, "杭州九堡");
		System.out.println(p01);
		
		//p01.show();
		
		System.out.println(p01.getClass().getName() + "@" + Integer.toHexString(p01.hashCode()));
	
	}
}


class Person{
	// 属性
	String name;
	int age;
	String addr;
	int weight;
	int height;
	String gender;
	String hobby;
	String info;
	
	public Person() {
		super();
	}

	public Person(String name, int age, String addr) {
		super();
		this.name = name;
		this.age = age;
		this.addr = addr;
	}

	public Person(String name, int age, String addr, int weight, int height, String gender, String hobby, String info) {
		super();
		this.name = name;
		this.age = age;
		this.addr = addr;
		this.weight = weight;
		this.height = height;
		this.gender = gender;
		this.hobby = hobby;
		this.info = info;
	}

	// 方法
	public void show() {
		System.out.println("name:" + name + ",age:" + age + ",addr:" + addr);
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", addr=" + addr + ", weight=" + weight + ", height=" + height
				+ ", gender=" + gender + ", hobby=" + hobby + ", info=" + info + "]";
	}
}

7.5 equals

7.5.1 定义
  • Object中的一个方法,返回两个对象是否一致
  • 默认采用==进行比较
  • 可以通过重写自定义比较的规则
7.5.2 案例
package com.qf.obj;

public class Demo04 {
	public static void main(String[] args) {
		Human h01 = new Human("10010", "张三", 23);
		Human h02 = new Human("10010", "张三", 24);
		
		// == 比较运算符,比较对象的引用,地址值
		System.out.println(h01 == h02);
		
		// equals应该比较对象的内容
		System.out.println(h01.equals(h02));
	}
}

class Human{
	// 属性
	String id;
	String name;
	int age;
	
	public Human() {
		super();
	}

	public Human(String id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	/*
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		
		if (!(obj instanceof Human)) {
			return false;
		}
		
		Human h = (Human) obj;
		if (!h.id.equals(this.id)) {
			return false;
		}
		
		if (!h.name.equals(this.name)) {
			return false;
		}
		
		if (!(h.age == this.age)) {
			return false;
		}
		
		return true;
	}*/

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Human other = (Human) obj;
		if (age != other.age)
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}
7.5.3 equals和==
  • 相同点
    • 都是比较两个对象是否一致
    • 默认都是比较对象的地址值
  • 不同点
    • ==关系是一个运算符,equals是一个Object中的方法
    • ==可以比较基本类型数据和引用类型数据,equals只能比较引用类型数据
    • equals方法可以重写,可以自定义比较的规则,但是一般重写hashCode方法

7.6 finalize

  • 对象被当做垃圾回收之前执行的一个方法
  • 一般用来做一些收尾的工作
package com.qf.obj;

public class Demo05 {
	public static void main(String[] args) {
		System.out.println("开启main方法");
		for (int i = 0; i < 1000000; i++) {
			new Students("name" + i, 20+i);
		}
		
		System.out.println("main方法结束....");
	}
}

class Students{
	// 属性
	String name;
	int age;
	
	public Students(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	@Override
	protected void finalize() throws Throwable {
		System.out.println("名字是" + name + "的对象被当做垃圾回收啦lalalala");
	}

	@Override
	public String toString() {
		return "Students [name=" + name + ", age=" + age + "]";
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值