//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(); //手动通知回收垃圾
}
}
Java程序猿必学第十二篇——内部类与Object常用方法
最新推荐文章于 2024-10-12 22:35:37 发布