内部类
- 把类定义在其他类的内部,这个类就被称为内部类。
- 内部类访问特点
a:内部类可以直接访问外部类的成员,包括私有。
b:外部类要访问内部类的成员,必须创建对象。
成员内部类
- 修饰符
private 为了保证数据的安全性
static 为了方便访问数据
注意事项: a:静态内部类访问的外部类数据必须用静态修饰。
b: 成员方法可以是静态的也可以是非静态的。
成员内部类被静态修饰后的访问方式是:
格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);//30
System.out.println(this.num);//20
System.out.println(new Outer().num); //10
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
大家看会输出什么嘞?
嗯。。。好像有答案了,没事没事,肯定都会嘛,哈哈。
局部内部类要访问局部变量的话还有一点要注意:
局部内部类访问局部变量必须用final修饰
为什么呢?
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。
静态内部类
package laolao;
class didi{
public static void main(String[] args) {
new di();
new di.dada().eat();
}
}
class di {
static int age=10;
static class dada{
public void eat(){
int a = di.age;
System.out.println(a);
}
}
}
特点:
- 静态内部类访问的外部类数据必须用静态修饰。
- 成员方法可以是静态的也可以是非静态的
- 格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
匿名内部类
- 就是局部内部类的简化写法。
- 匿名内部类的使用前提:存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
- 格式:
new 类名或者接口名(){
重写方法;
} ;
例:
public abstract class Person//抽象类或interface Person 接口
{
public abstract void work();
}
new Person(){
public void work()
{
System.out.println("work"); }
}.work();
其实匿名内部类的本质就是一个继承了该类或者实现了该接口的一个子类匿名对象。
Object类
类层次结构的根类
Object 是一个顶层父类,所有类,都是直接或间接继承自他
1. Object类的hashCode()方法
public int hashCode()
a:返回该对象的哈希码值。默认情况下,该方法会根据对象
的地址来计算。
b:不同对象的,hashCode()一般来说不会相同。
但是,同一个对象的hashCode()值肯定相同。
c:不是对象的实际地址值,可以理解为逻辑地址值。
例:
public static void main(String[] args) {
// 空参构造 Object()
Object obj= new Object();
// int hashCode()
// 返回该对象的哈希码值。
int code = obj.hashCode();
int code2 = obj.hashCode();
System.out.println(code);
System.out.println(code2);
Object obj2 = new Object();
int hashCode = obj2.hashCode();
System.out.println(hashCode);
//不同对象的哈希码值是不一样
}
2. Object类的getClass()方法
public final Class getClass()
a:返回此 Object 的运行时类。
b:可以通过Class类中的一个方法,获取对象的真实类
的全名称。
public String getName()
例:
public static void main(String[] args) {
Object obj = new Object(); //Object.class->字节码对象
Object obj2 = new Object(); //Object.class->字节码对象
System.out.println(obj);
System.out.println(obj2);
System.out.println(obj == obj2);
//获取字节码文件对象 Object.class ----->JVM
Class aClass = obj.getClass();
Class aClass1 = obj2.getClass();
System.out.println(aClass == aClass1);// true
}
3. Object类的toString()方法
public String toString()
a:返回该对象的字符串表示。
源代码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
b:它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
c:由于默认情况下的数据对我们来说没有意义,一般建议重
写该方法, 将该类的所有的成员变量组成返回即可
4. Object类的equals()方法
指示其他某个对象是否与此对象“相等”。
源代码:
public boolean equals(Object obj) {
return (this == obj);
}
比较对象的引用没用太大意义,一般建议重写。
- ==和equals()的区别:
- = =操作比较的是两个变量的值是否相等,equals操作表示的两个变量是否是对同一个对象的引用,= =比较的是2个对象的地址,而equals比较的是2个对象的内容,显然,当equals为true时,= =不一定为true。
5. Object类的clone() 方法
clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把该方法的权限修饰符改为public
- 对象浅克隆要注意的细节:
- 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。
- Cloneable接口只不过是一个标识接口而已,没有任何方法。
- 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。使用clone()方法采用的是浅克隆的方式。
- 对象的浅克隆也不会调用到构造方法的。
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个狗粮类对象
DogFood dogFood = new DogFood("双汇王中王");
Dog dog = new Dog("小白", 23, dogFood);
dog.dogFood.name="金锣火腿肠";
//克隆狗对象
Dog dog2= (Dog) dog.clone();
dog2.name="旺财";
dog2.age=4;
dog2.dogFood.name = "泡面搭档火腿肠";
System.out.println("--------------------");
System.out.println(dog.name);
System.out.println(dog.age);
System.out.println(dog.dogFood.name); // 金锣火腿肠 泡面搭档火腿肠
System.out.println("--------------------");
System.out.println(dog2.name);
System.out.println(dog2.age);
System.out.println(dog2.dogFood.name); // 泡面搭档火腿肠
}
}
class Dog implements Cloneable{
String name;
int age;
//在这个Dog类里面维护着另一个类的对象
DogFood dogFood;
public Dog(String name, int age, DogFood dogFood) {
this.name = name;
this.age = age;
this.dogFood = dogFood;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class DogFood{
String name;
public DogFood(String name) {
this.name = name;
}
}
深克隆与浅克隆的区别:
象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份;而深克隆不只把该对象克隆,也把克隆对象中维护的另外一个对象也克隆一份。