java内部类

本文详细介绍了Java内部类的概念、使用场景及其优势。内部类可以访问外部类的私有数据,增强了封装性,同时提供了类似多继承的功能。通过实例展示了如何在不同情况下创建和使用内部类,强调了静态和非静态内部类的差异。此外,文章还讨论了如何通过内部类实现高内聚低耦合的设计原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内部类是一个定义在另一个类中的类。那为什么要使用内部类呢?其主要原因有以下三点:

  1. 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据
  2. 内部类可以对统一包中的其他数据隐藏起来,增强面向对象的封装性
  3. 当定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷

通过代码来理解一下:

先创建人Person这样一个类,看一下如何在类中创建内部类

public class Person {
    //对象属性
    private String[] sex = {"男","女"};//定义一个私有的sex数组赋值

    //创建内部类, 内部类最本质的语法就是在一个类中创建另一个类。类是可以嵌套的。
    class XiaoMing {

    }
}

也可以在前面加上public,公共类,也可以不加,是一个默认的类。

public class Person {
    //对象属性
    private String[] sex = {"男","女"};//定义一个私有的sex数组赋值

    public class XiaoMing {

    }
}

加和不加public的区别?

加上public的类叫公共类,也叫主类。不加public就叫普通的类。

不加public也不报错,但是是一个普通的类。文件,在里面可以创建无数个类。向下面这样的写法这样的写法相当于写了三个文件,分别是Person.java,XiaoMing.java,  Xh.java。

class Person {
    //对象属性
    private String[] sex = {"男","女"};//定义一个私有的sex数组赋值
}
class XiaoMing {

}
class Xh {
}

可以写三个文件,也可以把他们合到一个文件里面写多个类。如果这里面没有公共类可以,但是能加public的公共类只能有一个,且文件名称必须要和主类的文件名称相同。

所以只能Person为主类。

再建一个test.java,去使用那个类,

public class test {
    public static void main(String[] args) {
        new Person();//在堆中开辟一个空间
    }
}

堆中开辟的空间变量如果没有在栈中去指向的话,java里面有个jvm,垃圾处理机制虚拟机会把没有用的会回收掉。但是要证明主类跟普通类区别的时候可以补全,可以说明这个类能够用到

public class test {
    public static void main(String[] args) {
        Person person = new Person();//在堆中开辟一个空间
    }
}

再一个类(可以补全),也可以用

public class test {
    public static void main(String[] args) {
       Person person = new Person();//在堆中开辟一个空间

        
        new XiaoMing();
    }
}

在其他包里的类的主方法里 new Person();不同包的需要引入:import .....

也可以用,当new XiaoMing();时有错误,主动引入导入 会出现 is not visible;不可见,所以区别有了,公共类可以在任何其他的类中使用,普通类只能在同包内使用, 范围更小。语法不在于好坏,在于它的价值是多少。

高内聚低耦合

需要main方法的时候,可以在下面写一个类。

内部类可以加public,也可以不加。相当于一个块里面又一个块,内部类里可以加多加public。

public class Person {
    public static void main(String[] args) {
       Person person = new Person();//在堆中开辟一个空间

        
        public class XiaoMing(){
            
        }
        public class XiaoMing1(){
            
        }
    }
}
public class Person {
    public static void main(String[] args) {
        private String[] sex = {"男","女"};       


        //创建内部类
        class XiaoMing(){
            private String Xiaoming_sex;//全局变量,只要不在函数体内的变量都叫全局变量

           private String showSex() {//前面用哪种都可以 private、public、protected、还有什么都不写。
                xiaoming_sex = "Xh";
                return "xiaoming_sex";
            } 
        }
      
    
}

看看内部域能不能访问外部域所有访问权限修饰符定义的变量的值,

public class Person {
    public static void main(String[] args) {
        private String[] sex = {"男","女"};       


        //创建内部类
        class XiaoMing(){
            private String Xiaoming_sex;

           private String showSex() {
                xiaoming_sex = sex[0];
                return "xiaoming_sex";
            } 
        }
          
}

怎么访问内部类?

public class Person {
    public static void main(String[] args) {
        private String[] sex = {"男","女"};       


        //创建内部类
        class XiaoMing(){
            private String Xiaoming_sex;

           private String showSex() {
                xiaoming_sex = sex[0];
                return "xiaoming_sex";
            } 
        }
       //创建对象方法,最好是公共的
           public void show_xiaoming_sex{
               XiaoMing xiaoMing = new XiaoMing();
               System.out.println(xiaoMing.showSex());
            }
}

相当于内部类就是一个变量,在这个外部不可以new的 但是在方法里面可以,咱们要把小明性别是男给返回出来,打印一下调用完的方法,这就是基本的语法。把内部类new了一个对象,调用内部类对象方法然后会有一个产物打印出来。就可以看到输出。

public class test {
    public static void main(String[] args) {
       Person person = new Person();
       person.show_xiaoming_sex();//调用一下这个方法
    }
}

我们本来可以把内部类的数据放到外面private下面,虽然private已经很安全了,以为只能是本类下访问,但是我们再包一层的话,只能在内部类外部new,去访问,更安全一些。就是在类中再套一个类,一个类就是一个防火墙,两个就是两个防火墙,所以更安全,增强封装性。

哪个类都可以写main方法,也可以不写,可以提出去,在里面进行创建,在test里进行调用,也可以合到一起。在下面建一个公共类,

public static void main(String[] args) {
		Person person = new Person();
		person.show_XiaoMing_sex();
	}

内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。这一点能够做到,为了能够运行程序,内部类的对象总有一个隐式引用,他指向了创建他的外部类对象

Xiaoming是一个内部类,里面有一个outer,里面包含了隐式引用一直指向person对象,所以里面的sex,等其他属性都可以访问到。

outer不是java关键字,我们只是用它说明内部类中的机制

重点:借助于内部类可以实现类似于多继承的作用。

再创建一个叫ZhangSan的类,并在张三这个类里再建一个ZuoJia的类,

public class ZhangSan extends ZuoJia {
	//创建两个内部类,用类extends继承作家、画家,已经具有了父类的两个方法
	class HuaJiaA extends HuaJia{
		
	}
	
	class ZuoJiaA extends ZuoJia{
		
	}
	
	
	
	public void xie() {

		ZuoJiaA zuoJiaA = new ZuoJiaA();//得到内部类的对象
		zuoJiaA.xie();
	}
	
	public void hua() {
		HuaJiaA huaJianA = new HuaJiaA();
		HuaJiaA.hua();
	}
	
	
	public static void main() {//调用zhangSan对象
		ZhangSan zhangSan = new ZhangSan();
		zhangSan.xie();//调写的方法
		zhangSan.hua();
	}
}
class ZuoJia {//作家——写
	public void xie() {
		System.out.println("写作");
	}
}

class HuaJia{//画家——画
	public static void hua() {
		System.out.println("画画");
	}
}


内部类的几种表现形式

一、非静态成员式内部类

定义:成员式内部类如同外部类的一个普通方法

成员式内部类有以下特性:

  1. 持有父类引用,故可以访问父类任何访问权限的变量、方法
  2. 非静态内部类中不能声明static成员

在对象方法中可以使用类属性。

public class ZhangSan extends ZuoJia {
	
	static String sex = "男";//类属性,在对象方法中可以使用类属性。
	//创建两个内部类,用类extends继承作家、画家,已经具有了父类的两个方法
	class HuaJiaA extends HuaJia{
		
	}
	
	class ZuoJiaA extends ZuoJia{
		
	}
	
	
	
	public void xie() {
        System.out.println("sex");//打印一下写 男
		ZuoJiaA zuoJiaA = new ZuoJiaA();//得到内部类的对象
		zuoJiaA.xie();
	}
	
	public void hua() {
		HuaJiaA huaJianA = new HuaJiaA();
		HuaJiaA.hua();
	}
	
	
	public static void main() {//调用zhangSan对象
		ZhangSan zhangSan = new ZhangSan();
		zhangSan.xie();//调写的方法
		zhangSan.hua();
	}
}
class ZuoJia {//作家——写
	public void xie() {
		System.out.println("写作");
	}
}

class HuaJia{//画家——画
	public static void hua() {
		System.out.println("画画");
	}
}


然后把属性定义为对象属性,方法为static ,反过来访问不到

public class ZhangSan extends ZuoJia {
	
	String sex = "男";//对象属性

	public static void xie() {//静态方法
        System.out.println("sex");

	}
	
	public static void main() {//调用zhangSan对象

	}
}

对象方法中可以使用静态变量,而静态方法中不能使用对象变量(属性)。再一个普通的属性objattr 

对象方法可以使用对象属性,也可以使用类属性,而类方法只能只能类属性;

静态方法中可以使用静态属性,也可以使用非静态属性。

public class ZhangSan extends ZuoJia {
	
	oublic static String classAttr = "静态属性(类属性)";//对象属性
    public String objAttr = "对象属性";

	//非静态方法(对象方法)
	public void objFun() {
		System.out.println(classAttr);
		System.out.println(objAttr);
	}
	//静态方法(类方法)
	public static void classFun() {
		System.out.println(classAttr);
	}
	
	public static void main() {//调用zhangSan对象

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值