目录
一.成员内部类
特点:
内部类的使用方法
成员内部类对象的创建:
二.静态内部类
定义
特点
对象创建方法
三.方法内部类(局部内部类)
定义
特点
四.匿名内部类
定义
特点
内部类就是将类结构的定义套在另一个类的内部,内部类的例子在我们现实生活中其实处处可见。汽车里面的发动机,衣服里面的棉花等等,发动机类就套在汽车类的内部,棉花类也是如此。
内部类也属于一种封装,它体现了一种保护性,例如发动机不能裸露在汽车的外部,这样就失去了安全性,在编程中也是同样的道理。
内部类一共分为四种:
定义:直接定义在类中,不加任何修饰符(static)定义的类,就是成员内部类
代码示例:
public class Test {
class Inner{
}
}
这里的Inner类就是内部类
public class Test {
private class Inner{
}
}
可以看到,内部类前面也可加private修饰符,表示它是私有内部类,对外部完全隐藏,只在Test类的内部使用
内部类和外部类可以方便的互相访问彼此的private域
代码示例:
public class Test {
private String msg = "外部类的msg属性";
public class Inner{
private int num = 10;
public void test(){
//直接访问外部类的属性
System.out.println(msg);
}
}
//注意fun方法不在内部类里面
public void fun(){
//创建内部类对象来访问内部类的私有属性
Inner inner = new Inner();
System.out.println(inner.num);
inner.test();
}
public static void main(String[] args) {
Test t = new Test4();
t.fun();
}
}
//输出结果:
10
外部类的msg属性
1.成员内部类的创建需要依赖外部类对象,没有外部类对象就无法创建成员内部类的对象(就像心脏类,在没有人体的情况下,就无法创建心脏这个对象)
2.内部类是一个相对独立的实体,和继承不同。内部类与外部类不是 is a 关系(心脏 is not a 人)
3.!!重要!!内部类可以直接访问外部类的元素和方法,包括私有域;而外部必须通过内部类的对象来访问内部类的元素和方法,包括私有域。
例如上面的例子,fun方法中,是创建了内部类的对象来访问内部类中的属性和方法的,而在Inner类中可以直接访问外部类的msg属性
那么
外部创建的代码示例:
public class A {
public static void main(String[] args) {
Test4.Inner inner = new Test4().new Inner();
inner.test();
}
}
此时若内部类Inner访问权限为private,对应A类时完全不可见的,我们设置内部类权限为public
5.内部类可以变相的实现“多继承”
代码示例:
class X{
int numX = 10;
}
class Y{
int numY = 20;
}
public class E {
//此处C、D是内部类
class C extends X{}
class D extends Y{}
public void test(){
C c = new C();
D d = new D();
System.out.println(c.numX);
System.out.println(d.numY);
}
public static void main(String[] args) {
E e = new E();
e.test();
}
}
//输出:10
20
思考:
成员内部类可以定义一个静态变量吗
成员内部内必须依赖外部类,若成员内部类有静态属性,没有外部类对象也可以访问,这和必须依赖外部类就相互矛盾了(类比成员变量)——所以答案是不能
对于外部类来说,能否在外部类的静态方法中使用成员内部类呢?
这就相当于在静态方法中调用成员方法——所以答案是不能
静态内部类就是定义在类中,使用static修饰的内部类。
public class Outter {
//静态内部类
static class Inner{
}
public static void main(String[] args) {
Inner inner = new Inner();
}
}
可以看到在内部类没有依赖外部类直接创建了对象 。
public class Outter {
static class Inner{
}
//外部类的成员方法
public void fun(){
Inner inner = new Inner();
}
//外部类的静态方法
public static void main(String[] args) {
Inner inner = new Inner();
}
}
这里为什么成员方法和静态方法都能创建内部类的对象呢?类比类中的静态变量,没有类的对象就可调用,有对象依然可以调用。
语法:外部类.内部类 引用 = new 外部类.内部类();
如:Outter.Inner inner = new Outter.Inner();
直接定义在方法内部的类,不允许使用任何修饰符,对外部完全隐藏,也就是说,出了这个方法,这个类就没有了。
public void fun(){
//方法内部类
class Inner{
}
}
1.方法内部无法定义static域,就像成员方法不能定义static变量。除此之外和成员内部类的基本统发相同
2.方法内部若使用了方法的形参,JDK8之后认定该形参为隐式的final声明,JDK8之前的形参必须使用final声明。
public class Outter {
public void fun(int num){
//方法内部类
class Inner{}
//此时Inner没有使用num变量
num++;
System.out.println(num);
}
public static void main(String[] args) {
Outter o = new Outter();
o.fun(10);
}
}
//输出:11
当我们在内部类中改变形参时就会报错,即使是在外部改变变量,在内部类中依然会报错,因为内部类使用了num变量,它就变为了隐式的final变量,值就不能修改
是lambda表达式的前身,函数式编程。它是方法内部类的特殊版本,直接不写类名称
匿名内部类遵从方法内部类的所有要求,同时匿名内部类会继续一个类(普通类和抽象类都可以)或实现一个接口。通常参数传递时使用
我们之前使用的接口传参使用:
public class Outter {
public static void fun(IMessage msg){
msg.printMsg();
}
public static void main(String[] args) {
IMessage msg = new IMessageImpl() ;
fun(msg);
}
}
interface IMessage{
void printMsg();
}
class IMessageImpl implements IMessage{
@Override
public void printMsg() {
System.out.println("普通用法");
}
}
//输出:普通方法
使用匿名内部类:
public class Outter {
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("匿名内部类的用法");
}
});
}
}
interface IMessage{
void printMsg();
}
//输出:匿名内部类的用法
学习JAVA基础的小伙伴初始内部类,我们只要了解四种内部类的不同和定义方法,在以后学习时再做进一步了解。