Java程序猿必学第十二篇——内部类与Object常用方法

//1. 内部类

// 1.1 静态内部类
//静态内部类:需要+static进行修饰的内部类
//使用特点: 在静态内部类中,不能使用外部类的成员属性

class Outter{
	private static int a = 1;
	private int b = 2;
	
	public static class Inner{
		public void test() {
			System.out.println(a);
			//System.out.println(b);  //加载时机问题
		}
	}
}

public class Test1 {
	public static void main(String[] args) {
		//调用静态内部类方式1:
		Outter.Inner inner = new Outter.Inner();
		inner.test();
		
		//直接new一个静态内部类方式2:
		Inner inner2 = new Inner();
		
	}
}




//1.2 局部内部类
//局部内部类:在外部类的方法中定义的一个类; 外界是不能调用的
//不能在局部内部类中加权限修饰--例如:public权限
//局部内部类,只能在方法内部去调用它
class Outter{
	private String name="凤姐";
	public void show() {
		final String name2 = "刘亦菲"; //在局部内部类中如果使用了外部类的局部变量,则会默认+final
		class Inner{
			private String name = "芙蓉";
			public void test(){
				System.out.println("局部内部类的方法--"+name); //芙蓉
				System.out.println(Outter.this.name);   //凤姐
				System.out.println(name2);  //刘亦菲
			}
		}
		
		new Inner().test();  //在外部类方法中才能调局部内部类
	}
}

public class Test1 {
	public static void main(String[] args) {
		new Outter().show();
	}
}



//1.3 匿名内部类(重点)

//匿名内部类:本质就是多态,只要能用上之前的抽象类或接口实现多态,则肯定能用匿名内部类

======================直接赋值的匿名内部类=====================

//案例:喷火娃具备喷火的能力
//分析:   
//类              Person       Fireable接口
//方法:          重写fire       fire

interface Fireable{
	void fire();
}

class Person implements Fireable{

	@Override
	public void fire() {
		System.out.println("喷火娃在喷火...");
	}
	
}

public class Test1 {
	public static void main(String[] args) {
		//---接口实现多态---
		Fireable fireable = new Person();
		fireable.fire();
		
		//----匿名内部类----
		Fireable fireable2 = new Fireable() {
			
			@Override
			public void fire() {
				System.out.println("匿名内部类在喷火...");
			}
		};
		fireable2.fire();
	}
}




//======================传参形式的匿名内部类=====================

 
//匿名内部类以传参形式出现:
//案例:电脑连接usb的鼠标

//匿名内部类与接口实现多态的应用场景:
//当项目中需要多次实例化对象---接口实现多态
//当进行简单测试或实例化一次对象时---匿名内部类

interface USB{
	void run();
}

class Mouse implements USB{

	@Override
	public void run() {
		System.out.println("鼠标正在运转..");
	}
}

class Computer{
	public void connect(USB usb) {
		usb.run();  //接口
	}
}

public class Test2 {
	public static void main(String[] args) {
		//接口以传参形式实现多态
		new Computer().connect(new Mouse());
		
		//匿名内部类:以传参形式出现
		new Computer().connect(new USB() {
			
			@Override
			public void run() {
				System.out.println("匿名内部类,以传参方式出现---run重写");
			}
		});
		
	}
}



//======================匿名内部类扩展案例=====================
/**

匿名内部类的扩展应用:
案例: 使用工具类,测试一段代码执行的时间,要求使用匿名内部内方式进行接口回调
提示:
测试时间的方法:System.currentTimeMillis()

分析:    
接口:       ITest   标准:codeTest
工具类:    Tool    静态方法: getTime;


好处:使用匿名内部类后,使得程序的扩展性,维护性,复用性更强
说明:在后续的过滤器,拦截器,spring内部源码都有匿名内部类的思想
 
 */

interface ITest{
	void codeTest();
}

class Tool{
	public static long getTime(ITest test) {
		long start = System.currentTimeMillis();
		
		test.codeTest();  //接口回调
		
		long end = System.currentTimeMillis();
		return end-start;
	}
}

public class Test3 {
	public static void main(String[] args) {
		/*
		long start = System.currentTimeMillis();
		//执行的代码
		long end = System.currentTimeMillis();
		System.out.println(end-start);
		*/
		
		long timer = Tool.getTime(new ITest() {
			
			@Override
			public void codeTest() {
				//放测试代码的区域
				String s = "";
				for(int i=0;i<10000;i++) {
					s+=i;
				}
			}
		});
		System.out.println(timer);
		
	}
}





//2.Object类

//2.1 Object基本操作(重点)
//Object类:老祖宗类,所有类直接或间接继承Object
//Object类中的方法是所有类都具有的方法---继承性

//Object中的多态使用:
//1.直接Object引用子类对象
//2.Object引用传参方式接收对象
//3.Object以返回值方式接收对象

class Son{
	
}  
public class BasicTest {
	public static void main(String[] args) {
		Object obj1 = new Son();  //多态核心--父类引用直接指向子类对象
		
		test(new Son());
		
		Object obj3 = getSon();  //以返回值方式实现多态
	}

	private static Object getSon() {
		return new Son();
	}

	private static void test(Object obj) { //Object以传参方式实现多态
		
	}
}



//2.2 Object的getClass方法
//getClass方法: 获取Object类的类对象

class Person{
	
}
public class ClassTest {
	public static void main(String[] args) {
		Class class1 = new Object().getClass();  //获取Object的类对象
		Class class2 = new Object().getClass(); 
		//获取类对象,只要调用对象所在类是同一个类,那么类对象就是同一个
		System.out.println(class1==class2);  //true---反射机制
		
		Class class3 = new Person().getClass();
		Class class4 = new Person().getClass();
		System.out.println(class3==class4); //true--两个都是Person类的对象,所以类对象一致
	}
}


//2.3.Object的hashCode方法(重点)
//Object的hashCode:每个不同对象都会得到一个唯一的hash值(整数值)
//应用场景:new不同对象,根据相同属性设置,决定hashCode一致

//案例: 获取自定义对象的hashCode
//目的: 属性一致,则hash值相同,如何做?
//解决方案---重写,父类的方法不适用我,我需要重写
class Student{
	String name;
	public Student(String name) {
		this.name = name;
	}
	
	@Override
	public int hashCode(){
		//重写后,将调用Object的hashCode转为了调用String类型的hashCode
		return name.hashCode(); //返回属性的hashCode
	}
}
public class HashCodeTest {
	public static void main(String[] args) {
		System.out.println(new Object().hashCode());  //不同对象,两个打印的hashCode不同
		System.out.println(new Object().hashCode());
		
		
		System.out.println(new Student("fengjie").hashCode());
		System.out.println(new Student("fengjie").hashCode());
	}
} 

 



//2.3 toString方法(重点)

//Object的toString:用于打印类名@hash值
//应用场景:toString一般用于打印自身对象,返回属性值的打印
//处理方案:重写自定义类的toString方法

class Teacher{
	private String name;
	public Teacher(String name) {
		this.name = name;
	}
	
	@Override  //重写Object的toString方法,返回属性值
	public String toString() {
		return name;
	}
}

public class ToStringTest {
	public static void main(String[] args) {
		Object obj = new Object();
		System.out.println(obj.toString()); //java.lang.Object@15db9742
		
		Teacher teacher = new Teacher("fengjie");
		System.out.println(teacher.toString()); 
		
		//简化版打印对象:
		System.out.println(teacher);
	}
}




//2.4.equals方法(重点)

//Object的equals方法:
//比较两个对象是同一个对象,返回结果才为true, 等价于‘==’

//案例:自定义对象比较相等
//应用场景:  往往属性值一致,则认为是同一个对象
//问题: 传入相同属性名,但是调的依然是Object的equals方法,还是比较地址
//解决方案: 重写equals,按自己方式比较属性值
class Star{

	private String name;
	public Star(String name) {
		this.name = name;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Star) {
			Star star = (Star) obj;
			//转为了属性String的equals的调用,String的equals方法就是比较内容的
			return this.name.equals(star.name);
			
		}else {
			return false;
		}
		
	}
	
}
public class EqualsTest {
	public static void main(String[] args) {
		Object object = new Object();
		System.out.println(object.equals(object));  //true
		System.out.println(object==object);  //true
		
		
		Star star = new Star("furong");
		System.out.println(star.equals(new Star("furong"))); //true
		System.out.println(star.equals("furong"));   //false
	}
}

 



//2.5. finalize方法

//当程序中出现垃圾对象时,jvm可以通过gc(垃圾回收器),将垃圾对象进行回收
//垃圾对象:就是new出来的对象,没有人使用
//两种垃圾回收方式:
//1.自动回收:当程序内存耗尽时,jvm会一次性将垃圾对象回收
//2.手动回收:调用System.gc(),通知jvm需要进行垃圾回收了(调用finalize方法),一般都会延时回收

class Woman{

	private String name;
	public Woman(String name) {
		this.name = name;
	}
	
	@Override  //通过jvm需要回收垃圾的触发
	protected void finalize() throws Throwable {
		System.out.println(name+"已经被回收了");
	}
	
}

public class FinalizeTest {
	public static void main(String[] args) {
		Woman woman = new Woman("刘亦菲");  //new的对象有人用
		
		new Woman("凤姐");  //new的对象没人用--垃圾对象
		
		System.gc();  //手动通知回收垃圾
	}
}




猜你喜欢

转载自blog.csdn.net/m0_62718093/article/details/120976919
今日推荐