Java学习之路-内部类,匿名内部类的使用方式和注意事项

正文:

“内部类"简单说就是在一个类的内部又定义了一个类,这个定义在已知类内部的类就称为"内部类”。由于是定义在一个已知类的内部,所以它既具备一个累的特征,又在很多方面的表现和普通类有不同。

下面,我打算从三个方面来讲解内部类的使用,并验证内部类的概念:

一、普通类中定义内部类(不常见)

"内部类"虽然有不同于普通类的特性,但是它终归是类,是类就必须能创建对象并调用其中的方法来执行功能,这是定义类的意义。

我们来写一个例子,看看内部类的属性是怎么调用的:

public class innerTest {
	int num = 100;
	private class inner{
		int num = 200;
		public void print(){
			int num = 500;
			System.out.println(num);				//方法内属性
			System.out.println(this.num);			//内部类属性
			System.out.println(innerTest.this.num);	//外部类属性
		}
	}
	public static void main(String[] args) {
		innerTest innerT = new innerTest();
		innerTest.inner inner = inner.new inner();
		inner .print();
		System.out.println(innerT.num + inner .num);	//调用内部类的num属性
	}
}
// 输出结果分别为:500,200,100,300

 
 

内部类的特性:

  1. "内部类"中可以定义属性,这些属性可以被其所在的普通类访问,甚至是可以访问"内部类"的私有属性(private)。当这些属性出现重名情况时,需要进行访问限定修饰;
  2. 普通类的内部可以定义多个内部类和接口,并且具备继承、实现的关系;
  3. 用static关键字,升级为顶级内部类,具备和普通类相同的特征,一模一样;
  4. "内部类"可以再进一步进行嵌套,构建对象时则需要按层进行构建。
二、方法中定义内部类(了解)

方法中也可以定义"内部类",方法中的"内部类"在事件处理中比较常见,在jdk1.8版本之前如果"内部类"需要访问其所在方法中的局部属性,则这个局部属性需要用final修饰。jdk1.8版本就不需要进行这个操作了,但是其本质还是final的,是不能对其进行修改的,看一个例子:

public class innerTest {
	public void innerMethod(){
		int num = 100;
		class innerClass{
			public void print(){
				System.out.println("可以访问方法的属性,但不可以修改:"+num);
			}
		}
		innerClass inner = new innerClass();
		inner.print();
	}
	public static void main(String[] args) {
		innerTest inner = new innerTest();
		inner.innerMethod();
	}	
}
//输出结果为:可以访问方法的属性,但不可以修改:100

 
 
三、匿名内部类(常用)

在实际开发中,我们通常用“匿名内部类”的方式来代替上面在方法中定义内部类的情况,它的写法简化很多,但意义是一样的,下面我们介绍一下:

顾名思义,匿名内部类也就是没有名字的内部类。正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码的编写。

在使用匿名内部类时,要记住以下几个原则:

  • 匿名内部类不能有构造方法;
  • 匿名内部类不能定义任何静态成员、方法和类;
  • 匿名内部类不能是public,protected,private,static;
  • 只能创建匿名内部类的一个实例;
  • 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类;
  • 因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

下面我讲述一下“匿名内部类”存在的意义:

abstract class Person {
    public abstract void speak();
}

class Child extends Person {
public void speak() {
System.out.println(“代码很冗余的说!!”);
}
}

public class Demo {
public static void main(String[] args) {
Person p =new Child();
p.speak();
}
}

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用。但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类,它存在的意义就是为了简化冗余的代码,如下:

abstract class Person {
    public abstract void speak();
}

public class Demo {
public static void main(String[] args) {
Person p =new Person() {
public void speak() {
System.out.println(“代码是不是清爽了很多??”);
}
};
p.speak();
}
}

噔噔噔噔~~ 是不是很清爽了,我们直接将抽象类Person中的方法在大括号中实现了!

其实,只要是抽象类或是接口,那么其子类中的方法都可以使用匿名内部类来实现,最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。

常用的匿名内部类实现:

  1. Thread类的匿名内部类实现
public class ThreadDemo {
    public static void main(String[] args) {
        Thread t =new Thread() {
            public void run() {
                for(int i = 1; i <= 5; i++) {
                    System.out.print(i +",");
                }
            }
        };
        t.start();
    }
}
//输出结果:1,2,3,4,5,

 
 
  1. Runnable接口的匿名内部类实现
public class RunnableDemo {
    public static void main(String[] args) {
        Runnable r =new Runnable() {
            public void run() {
                for(int i = 1; i <= 5; i++) {
                    System.out.print(i +" ");
                }
            }
        };
        Thread t =new Thread(r);
        t.start();
    }
}
//输出结果:1,2,3,4,5,

 
 
小结
  1. "内部类"中可以定义属性,这些属性可以被其所在的普通类访问。当这些属性出现重名情况时,需要进行访问限定修饰;
  2. 用static关键字,升级为顶级内部类,具备和普通类相同的特征,一模一样;
  3. 方法中定义的内部类,只能访问方法中定义的final类型的局部变量;
  4. 使用匿名内部类,必须继承一个父类或实现一个接口,这点很重要!!

特此声明:本文章为转载文章,仅作为学习参考,便于日后温习为目的,恭请少数关注的博友,直接点击转载博文的标题,链入原文,也算尊重原文作者的劳动。


本文链接:https://blog.csdn.net/weixin_44259720/article/details/87918110

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值