目录
1.内部类
1.1实例内部类
1.2静态内部类
1.3局部内部类
1.4匿名内部类
2.Object类
2.1getClass方法
2.2equals方法
2.3hashcode方法
1.内部类
定义:一个类定义在另一个类或一个方法的内部,前者称为内部类,后者称为外部类。
分类:实例内部类,静态内部类,局部内部类,匿名内部类。
1.1实例内部类
注意:1> 外部类中的任何成员都可以在实力内部类中直接访问(private也可以);
2> 实力内部类所处的位置与外部类成员位置相同,因此也受public,private等访问限定符的约束;
3> 访问成员时优先内部类,要想访问外部类同名的成员,必须通过外部类类名.this.同名成员来访问;
4> 实力内部类对象必须在先有外部类对象的前提下创建(这也是其缺点之一);
5> 外部类若想访问内部类的成员必须创建内部类对象。
class OuterClass {
public int data1 = 1;
private int data2 = 2;
private static int data3 = 3;
//实例内部类:类里面,方法外面
class InnerClass {
public int data1 = 10;
public int data4 = 4;
private int data5 = 5;
//public static int data6 = 6;//实力内部类中不能定义静态变量
//原因:此变量不依赖对象,但是InnerClass类依赖对象
public static final int data7 = 7;//加上final即可,此时该变量为常量,在编译时就已确定
public void testInner() {
System.out.println("testInner");
System.out.println(data1);//优先访问内部类成员
System.out.println(OuterClass.this.data1);//利用外部类名和this访问外部类成员
System.out.println(data5); //说明实例内部类存在外部类的this
}
}
public void testOut() {
//外部类若想访问内部类的成员必须创建内部类对象
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.data5);//5
}
}
public class Main {
public static void main(String[] args) {
//实例化实例内部类对象
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
OuterClass.InnerClass innerClas2 = new OuterClass().new InnerClass();//将上面两行代码合二为一
innerClas2.testInner();
}
}
1.2静态内部类
注意:1> 创建内部类对象时不需要先创建外部类对象;
2> 在静态内部类中只能访问外部类中的静态成员。
class OuterClass {
public int data1 = 1;
private int data2 = 2;
private static int data3 = 3;
//静态内部类
static class InnerClass {
public int data4 = 4;
private int data5 = 5;
public static int data6 = 6;//可定义静态成员变量
public void testInner() {
System.out.println("testInner");
System.out.println(data3);//可以访问外部类的静态成员
//System.out.println(data1);//无法访问外部类非静态成员
//System.out.println(OuterClass.this.data2);//使用外部类名.this也不可以
//解决方法:new一个外部类对象
OuterClass outerClass = new OuterClass();
System.out.println(outerClass.data1);
System.out.println(outerClass.data2);
}
}
}
public class Test {
public static void main(String[] args) {
//实例化静态内部类
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();//不需要创建外部类对象,注意和实例内部类的区别
innerClass.testInner();
}
}
1.3局部内部类
注意:1> 只能在所定义的方法体内部使用;
2> 不能被public、static等修饰符修饰;
class OuterClass {
public void test() {
//局部内部类:方法里面
class InnerClass {
public int data1 = 1;
}
//只能在所定义的方法体内部使用
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.data1);
}
}
1.4匿名内部类
语法奇奇怪怪QAQ……但是之后会很常用,只能死记啦 o.O
class Student implements Comparable<Student> {
@Override
public int compareTo(Student o) {
return 0;
}
}
interface Shape {
void draw();
}
public class Test {
public static void main(String[] args) {
Comparable<Student> comparable = new Student();
//匿名内部类:相当于这里有一个类实现了Comparable接口并重写了compareTo方法
new Comparable<Student>() {
@Override
public int compareTo(Student o) {
return 0;
}
}; //注意这里的分号
int a = 10;
new Shape() {
@Override
public void draw() {
//a = 20;//在匿名内部类中,访问的变量不能改变
System.out.println(a);
}
}.draw(); //调用draw方法
}
}
2.Object类
定义:Object是Java默认提供的一个类,是参数的最高同一类型。除了Object类,所有的类都是存在继承关系的。默认所有类继承Object父类。
疑问:之前我们学过,一个类只能继承一个类,这里的意思是只能同时继承一个类。
例如:Dog类继承Animal类,而Animal类又默认继承Object类,所以Dog类间接继承了Object类,没有违背一个类只能继承一个类这一说明。
//使用Object类接收所有类的对象
class Student {
public int age;
public Student(int age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
Object object1 = new Student(1);//Object可接收所有类的对象
}
}
2.1getClass方法
public class Test {
public static void main(String[] args) {
Student student = new Student(10);
Class<?> c = student.getClass();//Class<?> 这里涉及到了泛型,在之后的数据结构中会讲解
System.out.println(c);//class Demo2.Student —— 在Demo2包下的Student类中
}
}
2.2equals方法
进入Object的equals方法后,我们发现代码仍是使用地址比较,所以若想比较数据大小,必须要重写equals方法:
import java.util.Objects;
class Student {
public int age;
public Student(int age) {
this.age = age;
}
@Override //根据自身需求重写equals方法
public boolean equals(Object obj) {
Student student = (Student) obj;
return age == student.age;
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student(10);
Student student2 = new Student(10);
System.out.println(student1==student2);//比较地址,false
//System.out.println(student1.equals(student2));//父类Object中的equals仍是比较地址,false
System.out.println(student1.equals(student2));//重写equals后比较年龄大小,true
}
}
2.3hashcode方法
定义:此方法帮我们算了一个具体的对象位置,用来确定对象在内存中存储的位置是否相同。一般在散列表中才有用,其他情况下无用。
import java.util.Objects;
class Student {
public int age;
public Student(int age) {
this.age = age;
}
@Override //使用Generate生成
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age;
}
@Override //使用Generate生成
public int hashCode() {
return Objects.hash(age);
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student(10);
Student student2 = new Student(10);//没重写hashCode:不一样
//System.out.println(student1.hashCode());//460141958
//System.out.println(student2.hashCode());//1163157884
//重写hashCode后:一样
System.out.println(student1.hashCode());//41
System.out.println(student2.hashCode());//41
}
}
狂补ing……