Java---内部类
Java---内部类
内部类的概念
内部类就是一个类内部包含另一个类
分类:
- 成员内部类
- 局部内部类(包含匿名内部类)
格式:
修饰符 class 外部类名称
{
修饰符 class 内部类名称
{
//
}
}
注意:内用外,随意访问;外用内,需要内部类对象.
代码示例
public class Body {
private String name;
public class Heart {
public void show() {
System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
}
public void method() {
System.out.println("我是内部类");
}
}
public void methodwai() {//外部类方法
System.out.println("我是外部类方法");
}
public Body(String name) {
this.name = name;
}
public Body() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用成员内部类
1.间接方法
2.直接方法
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
代码示例
间接方法
内部类
public class Body {
private String name;
public class Heart {
public void method() {
System.out.println("我是内部类方法");
System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
}
}
public void methodwai() {//外部类方法
System.out.println("我是外部类方法");
new Heart().method();//再内部类方法里面调用内部类
}
public Body(String name) {
this.name = name;
}
public Body() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Main方法
public class Main {
public static void main(String[] args) {
Body one =new Body();
one.methodwai();//调用外部类方法,里面含有内部类对象
}
}
直接使用
内部类
public class Body {
private String name;
public class Heart {
public void method() {
System.out.println("我是内部类方法");
System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
}
}
public void methodwai() {//外部类方法
System.out.println("我是外部类方法");
new Heart().method();//再内部类方法里面调用内部类
}
public Body(String name) {
this.name = name;
}
public Body() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Main方法
public class Main1 {
public static void main(String[] args) {
//使用外部类创建内部类对象来使用内部类
//第一个new body()实际上就是一个构造方法
Body.Heart one = new Body("小黑").new Heart();
one.method();
}
}
内部类的同名访问
如果出现了重名现象那么格式是,外部类名称.this.外部类成员变量名.
代码示例
内部类
public class Outher {
int num = 10;
public class Inter {
int num = 20;
public void show() {
int num = 30;
System.out.println(num);//就近原则成员变量
System.out.println(this.num);//调用本类当中的变量
System.out.println(Outher.this.num);//类名称.this.变量名
}
}
}
Main方法
public class Main {
public static void main(String[] args) {
//创建内部类
Outher.Inter one = new Outher().new Inter();
//外部类名称.内部类名称 变量名 = new 外部类名称().new 内部类名称();
one.show();
}
}
局部内部类定义
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类.
"局部":只有当前所属的方法才能使用它,出了这个方法就不能用了
注意事项:
修饰符
public>protected>(default)>private
定义一个类的时候,权限修饰符
- 外部类 pubilc /(default)
- 成员内部类 public/protected/(default)/private
- 局部内部类:什么都不写
代码示例
局部内部类
public class Outher {
public void method() {//只有这个成员方法才能访问这个局部内部类
class Inther {//局部内部类
int num=10;//成员变量
public void show() {//局部内部类方法
System.out.println(num);
}
}
Inther one = new Inther();
one.show();
}
}
Main方法
public class Main {
public static void main(String[] args) {
Outher one =new Outher();//创建外部类对象
one.method();//调用成员方法
}
}
局部内部类的final问题
局部内部类:如果希望访问在方法的局部变量:那么这个局部变量必须是[有效final的]
原因:
-
new出来的对象在堆内存中
-
局部变量是跟着方法走的,在栈内存当中
-
方法结束运行之后,会立刻出栈,局部变量就会消失
-
但是new出来的对象会在堆当中一直存在,直到垃圾回收为止
代码示例
内部类
public class Outher {
public void method() {
int num = 30;//或者加上final
// num=20;//不可改变num的值
class Inner {
public void show() {
System.out.println(num);//直接访问局部变量,局部变量必须是有效final的
}
}
}
}
匿名内部类
如果接口的实现类(或者是父类的子类)只需要使用一次
那么这种群概况就可以省略该类的定义,而改为使用(匿名内部类)
格式:
接口名称 对象名 = new 接口名称(){
//覆盖重写所有的方法
};
代码示例
接口
public interface Interface {
public abstract void methd();//抽象方法
}
Main方法
public class Main {
public static void main(String[] args) {
Interface one = new Interface() {//匿名内部类,需要重写全部接口当中的全部的抽象方法
@Override//进行从写接口的方法
public void methd() {
System.out.println("匿名内部类重写了方法");
}
};//加上;
one.methd();
}
}
匿名内部类的注意事项
-
匿名内部类,在[创建对象]的时候只能使用唯一的一次
-
匿名对象,在[调用方法]的时候,只能调用唯一的一次
-
匿名内部类是省略了[实现类/子类名称],但是匿名对象,省略了[对象名称]
代码示例
接口
public interface Interface {
public abstract void methd1();//抽象方法
public abstract void methd2();//抽象方法
}
Main方法
public class Main {
public static void main(String[] args) {
//使用匿名内部类创建对象,匿名内部类是省略了类名称而不是对象名
Interface one = new Interface() {//匿名内部类,需要重写全部接口当中的全部的抽象方法
@Override//进行从写接口的方法
public void methd1() {
System.out.println("匿名内部类重写了方法 1111");
}
public void methd2() {
System.out.println("匿名内部类重写了方法 222");
}
};//加上;
one.methd1();
one.methd2();
Interface two = new Interface() {
@Override
public void methd1() {
System.out.println("匿名内部类重写了方法 1111");
}
@Override
public void methd2() {
System.out.println("匿名内部类重写了方法 222");
}
};
two.methd1();
two.methd2();
//下面来使用匿名内部类来创建匿名对象
//但是匿名对象只能调用唯一一次方法
new Interface(){
@Override
public void methd1() {
System.out.println("匿名内部类重写了方法 1111");
}
@Override
public void methd2() {
System.out.println("匿名内部类重写了方法 2222");
}
}.methd1();
new Interface(){
@Override
public void methd1() {
System.out.println("匿名内部类重写了方法 1111");
}
@Override
public void methd2() {
System.out.println("匿名内部类重写了方法 2222");
}
}.methd2();
}
}