提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
内部类
- 前言
- 一、成员内部类
- 二、静态内部类
- 三、方法内部类
- 四、匿名内部类
前言
内部类在Java的学习与应用中有着很大的作用,同时也起到了一定的封装作用。
一、成员内部类
内部类的使用方法:
a.内部类可以互相访问private属性
因为内部类隐藏了外部类的对象)所以在输出 val时,实际上是Test.this.val.
(2) 外部类必须通过内部类的对象来访问内部类的元素和方法,下列代码中student可以调用fun ()方法和private属性的age。
public class Test {
private int val=12;
private String str;
//-----------------------
class Student{
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public void fun(){
System.out.println(val);
}
}
//-------------------------
public void fun2(){
Student student=new Student(12,"张三");
student.fun();
System.out.println(student.age);
}
public static void main(String[] args) {
Test test=new Test();
test.fun2();
}
}
b.成员内部类的对象创建:
(1)外部类内部创建(此时的内部指的是Test这个类里面):
上述代码中fun2()方法,就创建了student对象。
(2)外部类的外部创建(此时就是在Test这个类的外面):
public class Test1 {
public static void main(String[] args) {
Test.Student student=new Test().new Student(45,"李四");
//输出结果是12
student.fun();
}
}
注意:对此由于内部类的创建必须依赖于外部类,所以一定要使用Test这个外部类来一步步产生 student对象。由于Student这个成员内部类在Test中是包访问权限,Test1与Student在同一个包下,因此Test1是可以看到的,如果将Studnt这个类加上private,此时上述代码就不可实现了,其实和成员方法有着很大的相似。
c.成员内部类其它:
(1)成员内部类不可以定义静态变量,可以访问外部类的成员域、静态域:
对于不可以定义静态变量我自己的理解:对于成员内部类(类比成员变量),必须依赖于外部 类,若定义了静态变量,则没有外部类对象也可以访问了。所以就会产生矛盾!
不可以直接在静态方法中使用成员内部类:
public static void fun2(){
Student student=new Student(12,"张三");
student.fun();
System.out.println(student.age);
}
此时上述代码是错误的:因为静态方法不需要产生外部类对象就可以通过类调用,而成员内部类必须依赖于外部类对象,所以是不可以的!
解决方法:可以在fun2()方法内部,通过外部类产生内部类对象。
public static void fun2(){
Test.Student student=new Test().new Student(21,"阿娇");
student.fun();
System.out.println(student.age);
}
好了到这里,这个问题已经变得很清楚了!!!
二、静态内部类
静态内部类:定义在类中,使用static修饰的内部类。
这里只需要在内部类加上static修饰就OK了!
public class Test {
private int val=12;
private String str;
//-----------------------
static class Student{
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public void fun(){
//此时就不可以直接访问外部类的成员变量val,当然如果val被static修饰就可以
//此时就要产生一个外部类对象
System.out.println(new Test().val);
}
}
//-------------------------
//此时如果是public static void fun2(),也可以直接使内部类。
public void fun2(){
Student student =new Student(45,"阿花");
student.fun();
}
public static void main(String[] args) {
Test test=new Test();
test.fun2();
}
}
所以只要那个成员内部类懂了,这个静态方法大同小异! 但还有以下值得注意的:
(1)静态内部类可以拥有成员变量。
(2)静态内部不可以直接外部类的成员变量,但可以new出来一个外部类的对象访问,上述代码fun (),方法中就体现出来了。
(3)在外部类的外部创建内部类的对象:
public class Test1 {
public static void main(String[] args) {
Test.Student student=new Test.Student(45,"小花");
student.fun();
}
}
此时相对于 成员内部类在外部类的外部创建内部类对象,有差点差别,因为静态内部类不需要产生对象,只需要使用类名称即可。
三、方法内部类
定义:定义在方法内部的类,不允许使用任何访问修饰符,对外部完全隐藏(出了这个方法就没了)
public class Test {
private int age = 10;
public void fun(int num) {
// 方法内部类,不能出现任何访问修饰符和static
class Inner {
public void test() {
System.out.println(age);
System.out.println(num);
}
}
// 此时Inner使用num这个变量,num就变为了隐式的final,值不能修改
Inner inner = new Inner();
inner.test();
}
public static void main(String[] args) {
Test test=new Test();
Test.fun(10);
}
}
注意:方法的内部类若使用了方法的形参,则该形参为隐式的声明,则该参数不可被修改。
四 、匿名内部类
定义:是方法内部类的特殊版本,直接不写类名称;遵从方内部类的所有要求,匿名内部类会默认继承一个类或接口。
public class Test {
public static void fun(IMessage msg) {
msg.printMsg();
}
public static void main(String[] args) {
fun(new IMessage() {
// 这就是一个匿名内部类
// 等同于创建了一个类实现了Imessage接口,创建该类的对象
@Override
public void printMsg() {
System.out.println("匿名内部类的用法");
}
});
// 上面的使用就等同于下面两行
// IMessage msg = new IMessageImpl();
// fun(msg);
}
}
interface IMessage {
void printMsg();
}
class IMessageImpl implements IMessage {
@Override
public void printMsg() {
System.out.println("普通用法");
}
}
这个是自己写的接口,自己实现的,上面显示了普通用法和匿名用法。通过比较很容易发现里面的关系。
但我们平时做题时,也经常会用到JDK自带的各种接口,例如comparator接口,也叫比较器。
Queue<Freq> queue=new PriorityQueue<>(new Comparator<Freq>() {
@Override
public int compare(Freq o1, Freq o2) {
return o2.times-o1.times;
}
});
这个就是采用匿名内部类实现了一个基于最大堆的优先级。
总结
这是我第一次尝试些博客,可能对排版啥的有些欠缺,希望大家伙理解哈。接下来那我一定还会将其他的一些知识,以一个比较容易理解的方式,呈现给大家,希望大家可以喜欢哦。滴 滴滴~~