}
}
在这里Outer是外部类,Inner是内部类,可以看出来Inner类在Outer类的里面
内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类
按照内部类在类中定义的位置不同,可以分为如下两种格式:
成员位置(成员内部类)
局部位置(局部内部类)
class Outer2{
//定义在成员位置,叫做成员内部类
class Inner{
//这是成员内部类
}
public void show(){
//定义在局部位置,叫做局部内部类
class Inner2{
//这是局部内部类
}
}
}
成员内部类
1、内部类可以访问外部类的成员,包括私有
2、正确的创建内部类的对象格式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
成员内部类举例
package review.InnerDemo;
class Outer2{
int num = 20;
private int num1 = 30;
class Inner2{
int num = 10;
public void show(){
System.out.println(num);//打印10,访问内部类的成员变量
System.out.println(Outer2.this.num);//打印20,访问外部类的成员变量
System.out.println(Outer2.this.num1);//打印30,访问外部类的私有成员变量
//Outer2.this.Outer_show();用this这种方式也可以调用方法
}
}
public void Outer_show(){
Inner2 i = new Inner2();
System.out.println(i.num); //打印10,访问内部类的成员变量
System.out.println(num); //打印20,访问外部类的成员变量
}
}
public class demo2 {
public static void main(String[] args) {
Outer2 o = new Outer2();
o.Outer_show();
System.out.println("============");
//不能直接创建内部类的对象
//Inner2 i = new Inner2();这样做会报错
//需要这样创建对象,外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer2.Inner2 inner2 = new Outer2().new Inner2();
inner2.show();
}
}
结果为
一般来说,在实际开发中是不会这样使用的。因为一般内部类就是不让外界直接访问的。
所以我们会给内部类加上修饰符
private 为了保证数据的安全性
package review.InnerDemo;
class Computer{
private class Chip{
public void function(){
System.out.println(“芯片工作”);
}
}
public void show(){
Chip c = new Chip();
c.function();
}
}
public class demo3 {
public static void main(String[] args) {
Computer
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
o = new Computer();
o.show();
//内部类加入了private权限修饰符之后,就不能被访问了
//Computer.Chip c = new Computer().new Chip();是错误的
}
}
芯片在电脑的里面,我们不希望芯片这个内部类被外界访问,所以用private修饰
这时我们只能在Computer类里面创建Chip类的对象,再由这个对象来调用成员变量或者成员方法。再像之前那样用外部类名.内部类名 对象名 = 外部类对象.内部类对象;的方法来创建内部类对象就不行了
那么有private修饰符,也有static修饰符
成员内部类加上一个static修饰符后变成静态内部类
格式为
class Outer{
static class Inner{
//静态内部类
}
}
static 为了让数据访问更方便
-
被静态修饰的成员内部类只能访问外部类的静态成员
-
静态内部类可以有静态成员,而非静态内部类则不能有静态成员(成员包括变量和方法)
-
非静态的成员内部类,成员只能是非静态的。
-
内部类被静态修饰后的方法有静态和非静态之分。他们的访问和不用静态是不一样的。
访问非静态方法:外部类名.内部类名 对象名 = new 外部类名.内部类名();
访问静态方法:上面创建的对象访问,或者外部类名.内部类名.方法名();
package review.InnerDemo;
class Computer1{
int num1 = 10;
static int num2 = 20;
public static class Chip1{
public static void show1(){ //内部类的静态方法
System.out.println(num2); //只能访问外部类的静态成员变量num2
System.out.println(“静态方法”);
}
public void show2(){ //内部类的非静态方法
System.out.println(“非静态方法”);
}
}
}
public class demo4 {
public static void main(String[] args) {
//访问非静态方法
Computer1.Chip1 c = new Computer1.Chip1();
c.show2();
System.out.println("==========");
//访问静态方法
c.show1();
System.out.println("==========");
//访问静态方法
Computer1.Chip1.show1();
}
}
结果为
局部内部类
-
可以直接访问外部类的成员
-
可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
局部内部类存在于方法中。
package review.InnerDemo;
class Outer3{
int num1 = 10;
public void show(){
int num2 = 20;
class Inner3{
int num3 = 30;
public void show2(){
System.out.println(num3);
System.out.println(num2);
System.out.println(num1);
}
}
//num2 = 40; 这里无法修改num2的值
//jdk1.8之后会自动在局部方法上的局部变量添加final
//System.out.println(num2);在这里打印的结果是num2 = 20
//创建内部类对象,通过对象调用成员变量
Inner3 i = new Inner3();
i.show2();
}
}
public class demo5 {
public static void main(String[] args) {
Outer3 o = new Outer3();
o.show();
}
}
结果为
局部内部类和成员内部类的区别
-
局部内部类的作用范围在方法或者作用域之内
-
局部内部类不能用public或private访问说明符进行声明
package review.InnerDemo;
class Outer3{
public void show(){
class Inner3{
public void show2(){
//这两种方式调用外部类的方法,结果是一样的
Outer3.this.test();
test();
}
}
Inner3 i = new Inner3();
i.show2();
}
public void test(){
System.out.println(“外部类方法”);
//要注意,不能在这里创建内部类的对象,超出局部内部类的作用范围
//Inner3 i = new Inner3();
}
}
public class demo5 {
public static void main(String[] args) {
Outer3 o = new Outer3();
o.show();
}
}
结果为
匿名内部类
就是内部类的简化写法。
前提:存在一个类或者接口。这里的类可以是具体类也可以是抽象类。
格式:
new 抽象类名或者接口名() {
重写方法;
}
先来看看如果不适用匿名内部类,应该怎么写
public interface interDemo {
public abstract void show1();
public abstract void show2();
}
abstract class abstractDemo {
public abstract void test();
}
class Inter implements interDemo{
public void show1(){
System.out.println(“show1”);
}
public void show2(){
System.out.println(“show2”);
}
}
public class Ab extends abstractDemo{
public void test(){
System.out.println(“test”);
}
}
public class demo1 {
public void function(){
Inter i = new Inter();
i.show1();
i.show2();
Ab a = new Ab();
a.test();
}
public static void main(String[] args) {
demo1 d = new demo1();
d.function();
}
}