🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:【Java】内容概括
【前言】
在 Java 面向对象编程中,抽象类、接口、内部类和 Object 类是核心概念,它们共同支撑了 Java 的封装、继承与多态特性。本文将从概念、用法、区别及实战场景等方面,详细解读这些核心知识点,并结合代码示例帮助理解。
文章目录:
一、内部类
内部类是定义在另一个类中的类,可分为成员内部类,局部内部类,匿名内部类和静态内部类。
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部完整的结构又只为外部提供服务,so这个内部完整的结构最好使用内部类。
内部类
:java中,可以将一个类定义在另一个类或者一个方法的内部,这个就是内部类和外部类;
语法格式:
public class OutClass {
public class InnerClass{
}
}
注意事项:
- 必须定义在类名内部;
- 内部类和外部类共用一个java源文件。但编译后会形成单独的字节码文件
1. 内部类的分类
内部类是定义在另一个类中的类,可分为成员内部类,局部内部类,匿名内部类和静态内部类。
public class OutClass {
//实例内部类
public class InnerClass{
}
//静态内部类
static class InnerClass1{
}
public void fun(){
//定义在方法中,局部内部类
class InnerClass2{
}
}
}
成员内部类
:实例内部类和静态内部类局部内部类
(无修饰符)匿名内部类
2. 静态内部类
public class OutClass {
public int a;
public static int b;
public class InnerClass{
public void fun2(){
//只能访问外部类的静态成员
b = 10;
}
}
public static void main(String[] args) {
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.fun2();
}
}
【注意】
- 静态内部类中只能访问外部类的静态成员
- 创建静态内部类时,不用先创建外部类对象
3. 实例内部类
未static
修饰的内部成员称为成员内部类
public class OutClass {
public int a;
public static int b;
public int c;
//实例内部类
public class InnerClass{
public void fun2(){
a = 10;
//实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
b = 20;
c = 30;
System.out.println(c);
//如果访问外部类同名成员时,必须:外部类名称.this.同名成员名字
OutClass.this.c = 50;
System.out.println(c);
}
}
public static void main(String[] args) {
//外部类:对象创建,成员访问
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(outClass.b);
System.out.println(outClass.c);
//创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass.new InnerClass();
//可以将外部类对象先创建出来,在创建内部类对象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.fun2();
}
}
【注意】
- 外部类中的任意成员都可以在实例内部类方法中访问
- 实例内部类所处的位置和外部类成员位置相同,因此,也受public,private等访问限定符约束
- 实例内部方法中访问同名成员时,优先访问自己的,访问外部时:
外部名称.this.同名成员
- 实例内部类对象必须先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问内部类中的成员,必须先创建内部类的对象
4. 局部内部类
public class OutClass {
int a = 10;
public void fun(){
int b = 20;
//局部内部类:定义在方法体内部
//不能被public.static等访问限定符修饰
class InnerClass{
public void funInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
}
【注意】
- 局部内部类只能在定义的方法体内部使用
- 不能被public , static 等修饰符修饰
5. 匿名内部类
无类名的内部类,用于简化接口或抽象类的实现,只能使用一次
public class Test {
public void test(){
System.out.println("执行");
}
public static void main(String[] args) {
new Test(){
@Override
public void test() {
super.test();
}
}.test();
}
}
在匿名内部类中,只能访问常量
和没有被改变的量
public static void main(String[] args) {
int a =100;
new Test(){
@Override
public void test() {
a = 150;//报错
}
}.test();
}
在匿名内部类里面,静态成员变量的就地初始化只有一次,后面不能修改
public static void main(String[] args) {
new Test(){
//在匿名内部类里面
public static int a = 10;
a = 10;
@Override
public void test() {
System.out.println(a);
}
}.test();
}
二、Object 类
Object 类是Java默认提供的一个类,是Java所有类的根类,所有的类默认继承Object父类,即所有类的对象都可以使用Object的引用来接收
eg:使⽤Object接收所有类的对象
class Person{}
class Student{}
public class Test {
public static void fun(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
fun(new Person());
fun(new Student());
fun(new Test());
}
}
Object类也存在有定义好的⼀些⽅法
方法名 | 作用 |
---|---|
toString() |
返回对象的字符串表示(默认是类名@哈希值) |
equals(Object obj) |
判断两个对象是否相等(默认比较地址) |
hashCode() |
返回对象的哈希码值 |
getClass() |
获取对象的运行时类 |
clone() |
复制对象(需实现 Cloneable 接口) |
wait()/notify() |
线程同步相关方法 |
1.获取对象信息
⽐较对象中内容是否相同的时候,⼀定要重写equals⽅法
// Object
类中的toString()⽅法实现:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
2.对象比较equals方法
// Object类中的equals⽅法
public boolean equals(Object obj) {
}
return (this == obj); //
使⽤引⽤中的地址直接来进⾏⽐较
class Student{
public String age;
public Student(String age){
this.age = age;
}
@Override
public String toString() {
return super.toString();
}
}
public class Test {
public static void fun(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
Student student1 = new Student("18");
Student student2 = new Student("18");
System.out.println(student1 == student2);
System.out.println(student1.equals(student2));
String s1 = new String("100");
String s2 = new String("100");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
}
String重写
Object重写
和比一至,需要自己重写
重写 equals 方法
public boolean equals(Object obj){
Student tmp = (Student) obj;
if(tmp.age.equals(this.age)){
return true;
}
return false;
}
3.hashcode 方法
通过hashcode方法可以算一个对象具体位置
- hashcode源码
public native int hashCode();
- 原生的hashcode,不能找到同一个位置
public static void main(String[] args) {
Student student1 = new Student("18");
Student student2 = new Student("18");
System.out.println(student1.hashCode());
System.out.println(student2.hashCode());
}
- 自己重写hashcode,调子类自己的hashcode
@Override
public int hashCode() {
return Objects.hash(age);//导包:Ait+回车
}
1、hashcode⽅法⽤来确定对象在内存中存储的位置是否相同
2、事实上hashCode()在散列表中才有⽤,在其它情况下没⽤。在散列表中hashCode()的作⽤是获取对象的散列码,进⽽确定该对象在散列表中的位置。
【定义类时】
- 实现可比较的接口:Comparable
- 重写equals 和 hashcode
三、总结
- 抽象类用于抽取共性,接口用于规范行为,二者配合实现多态设计。
- 内部类增强了类的封装性,匿名内部类简化了接口/抽象类的临时实现。
- Object 类是所有类的基础,重写其方法(如 toString() 、 equals() )可使类更符合业务需求。
掌握这些核心概念,能帮助我们设计更灵活、可扩展的 Java 程序。