第十五天
局部内部类
局部内部类是定义在外部类的成员方法中的一种类,它可以访问外部类的成员变量,即使是私有的也能去访问.
在外部类的局部位置,访问内部类的成员方法要去创建当前局部内部类的对象来进行访问.
//定义一个外部类
class Outer{
public int num = 100 ;
private int num2 = 200 ;
//成员方法
public void method(){
//局部位置:局部内部类
class Inner{
//局部内部类的一个成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
//创建局部内部类对象
Inner inner = new Inner() ;
inner.show() ;
}
}
//测试类
public class OuterDemo {
public static void main(String[] args) {
//访问方式:直接创建外部类类对象
//调用的成员方法
Outer outer = new Outer() ;
outer.method();
}
}
要注意的是,在JDK7版本下,如果局部内部类访问变量时,必须加入final进行修饰,之后的版本会自动默认添加所以不要紧.
class Outer2$1Inner2{ final int val$num; //num已经加入了final修 final Outer2 this$0; public void show(){ System.out.println(val$num); } Outer2$1Inner2(){ this.this$0 = this$0; val$num = I.this; super(); } }
那么我们为什么要添加final去修饰呢?这是因为局部变量的生命周期随着方法而存在和消失,在局部内部类创建完局部内部类对象,在方法结束后这个对象并不会立即消失,此时这个对象的内部成员方法去访问时当前变量消失了就会产生冲突,至此,为了避免局部内部类访问消失的变量,变量鼻血加入final去修饰.
匿名内部类
顾名思义,匿名内部类就是没有名称的内部类,一般在局部位置去使用它.本质上就是继承了该类,或者实现了该接口的字子类对象.
//定义一个接口
interface Inter{
void show() ; //public abstract修饰 (可以省略)
void show2() ;
}
/*class InterImpl implements Inter{
@Override
public void show() {
}
@Override
public void show2() {
}
}*/
//外部类
class Outer3{
//定义一个成员方法
public void method(){
// class Inner3{} 有名字内部类
//使用匿名内部类去写
/*
new 类名(可以是抽象类,也可以具体类)或者是接口名(){
重写功能
} ;
*/
//情况1:接口中只有一个方法
/* new Inter(){ //接口名
@Override
public void show() {
System.out.println("show Inter...");
}
}.show() ;*/
//情况2:接口中有两个方法
/* new Inter(){
@Override
public void show() {
System.out.println("show Inter...");
}
@Override
public void show2() {
System.out.println("show2 Inter...");
}
}.show() ;
new Inter(){
@Override
public void show() {
System.out.println("show Inter...");
}
@Override
public void show2() {
System.out.println("show2 Inter...");
}
}.show2() ;*/
//优化:给匿名内部类起一个名字
Inter i = new Inter(){
@Override
public void show() {
System.out.println("show Inter...");
}
@Override
public void show2() {
System.out.println("show2 Inter...");
}
};
i.show();
i.show2();
}
}
方法的形参如果是一个接口的话,呢么就需要实际传递接口的子实现类对象.如下
//抽象类
abstract class Person{
public abstract void work() ;
}
//PersonDemo类
class PersonDemo{
public void method(Person p){//方法的形式参数是一个抽象类
p.work();
}
}
//定义一个子类继承自Person类
class Student extends Person{
@Override
public void work() {
System.out.println("good good study ,day day up!!");
}
}
//测试类
public class PersonTest {
public static void main(String[] args) {
//调用PersonDemo类中的method方法?
//创建PersonDemo类对象 /或者匿名对象
PersonDemo pd = new PersonDemo() ;
//抽象类多态:创建子类对象
Person p = new Student() ; //定义一个子类Student
pd.method(p) ;
System.out.println("----------------------------------------");
//使用匿名内部类去完成:
/**
* new 类名(抽象类)/接口名(){
* 重写方法
* } ;
*/
//调用PersonDemo类中的method方法?
PersonDemo pd2 = new PersonDemo() ;
pd2.method(new Person(){ //实际参数也是传递抽象类的子类对象(抽象类的匿名内部类)
@Override
public void work() {
System.out.println("good good Study,day day Up!!");
}
});
}
}
通过匿名内部类可直接new一个子类对象当形参去调用.
Object
java.lang.Object;
Object类是所有类的根类,就是说所有类都默认继承Object类.
Object类中有许多常用的方法.如getClass()方法,就是返回当前类的全限定名称.
获取一个类的字节码文件对象一共有三种方式,分别是通过Object类的getClass()方法去获取,第二种就是通过任意java类型的class属性获取当前类的字节码文件对象Class,最后一种就是通过Class里面的forName(“类的全限定名称(包名.类名)”).
Object toString();
返回的是一个对象的字符串表示形式,结果应该是一个简明扼要的表达,让人容易阅读,建议所有的子类覆盖此方法.
描述一个对象,有很多的属性,应该看到具体的属性描述,要么使用手动方式去访问(在此不推荐),要么使用快捷键,toString即可.
public class ObjectDemo {
public static void main(String[] args) {
//通过有参构造方法创建一个学生对象
Student s = new Student("高圆圆",42) ;
//直接输出对象名称 --->会默认调用它的父类:Object的toString方法
System.out.println(s);//com.qf.object_06.Student@1540e19d
System.out.println("-----------------------------------");
/**
* Object类的toString方法的原码
* public String toString() {
* return getClass().getName() + "@" + Integer.toHexString(hashCode());
* }
*
* Integer类:int类型的包装类类型
* public static String toHexString(int i) :将整数转换成16进制数据--结果以String类型展示
*/
/*System.out.println(s.getClass().getName()+"@"+Integer.toHexString(s.hashCode()));
System.out.println(s.toString());*/
System.out.println(s.toString());
/*String str = new String("hello") ;
System.out.println(str);*/
}
}
Object类的equals()方法.
public boolean equals(Object obj)用来判断obj对象和当前的对象是否相等.
equals在Object中 默认比较的是两个对象的地址值是否相等,对equals进行重写以后就可用它比较两个类的值是否相同.