内部类
java中允许类的内部单独定义的一个类,那么每一个内部类去实现和继承其它的类与接口,对外部类不是造成任何的影响;
好处
1.在内部类中可以访问外部类私有化变量
2.每一个内部类去实现和继承其它的类与接口,对外部类不是造成任何的影响
缺点
1.造成代码冗余,不符合封装的思想
2.不符合高内聚,低耦合的设计思想,造成代码可维护性差
语法
class Out{
//外部类的变量
//外部类的方法
class In{
//内部类的变量
//内部类的方法
}
}
注意
1.java运行的最基本单位是类,c运行的基本单位是函数
2.每一个内部类都会编译生成单独的字节码文件(Out$In.class)
成员内部类
内部类像外部类的成员属性和成员方法一样,内部类需要依赖于外部类对象
语法
class Out{
//外部类的变量
//外部类的方法
class In{
//内部类的变量
//内部类的方法
}
}
注意
1.成员内部类中不能定义静态的属性和方法
2.成员内部类如何在方法中访问外部类的成员变量
a.当成员内部类的属性名和外部类的成员属性名没有重名时,直接调用
b:当成员内部类的属性名和外部类的成员属性名重名时
调用成员内部类的成员变量使用this.a
调用外部类的成员变量使用Out.this.a
3.如何得到成员内部类的对象
外部类名.内部类名 变量名=外部类对象.内部类对象
成员内部类编译生成的字节码文件是Out$In.class
package demo;
import java.io.Serializable;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午9:16:15 package demo; public class Out{ } 类说明
*/
public class Out {
//外部类的成员变量
int a=10;
//外部类的成员方法
public void fun() {
System.out.println("外部类的成员方法"+a);
}
//外部类的成员内部类
class In {
//内部类的成员变量
int a=20;
int b;
//static int a;//如果允许?Out.In.a?
//内部类的成员方法
public void fun() {
int a=15;
System.out.println("内部类的局部变量"+a);
System.out.println("内部类的成员变量"+this.a);
System.out.println("外部类的成员变量:"+Out.this.a);
System.out.println("内部类的成员方法"+b);
}
}
}
package demo;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午9:30:49
* package demo;
* public class Test{ }
* 类说明
*/
public class Test {
public static void main(String[] args) {
//如何去调用内部类的成员方法?
//1.得到外部类的对象
/*Out out=new Out();
//2.得到内部类的内部对象
Out.In in=out.new In();*/
//上述两步合并一下
Out.In in=new Out().new In();
in.fun();
}
}
静态内部类
使用static修饰的内部类,自动提升为普通类,相当于一个独立的类,和外部类级别相同,不依赖于外部类对象
class Out{
//外部类的变量
//外部类的方法
static class In{
//内部类的变量
//内部类的方法
}
}
注意
1.静态内部类可以去定义静态属性和方法
2.如何得到静态内部类对象
In in=new In();
3.单独使用静态内部类时,需要导包,格式是
import demo1.Out.In;
package demo1;
import java.io.Serializable;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午9:16:15 package demo; public class Out{ } 类说明
*/
public class Out {
//外部类的成员变量
int a=10;
//外部类的成员方法
public void fun() {
System.out.println("外部类的成员方法"+a);
}
//外部类的静态内部类
static class In {
//内部类的成员变量
static int c=15;
int b;
//static int a;//如果允许?Out.In.a?
//内部类的成员方法
public void fun() {
System.out.println("静态内部类的成员方法"+b);
}
}
}
package demo1;
import demo1.Out.In;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午9:55:10
* package demo1;
* public class Test{ }
* 类说明
*/
public class Test {
public static void main(String[] args) {
//静态内部类不依赖于外部类
Out.In in=new In();
in.fun();
System.out.println("打印静态内部类的静态属性"+In.c);
}
}
局部内部类
在方法内声明局部内部类,它的使用范围不能脱离方法
语法
class Out{
//外部类的变量
public void 方法名(){
class In{
//内部类的变量
//内部类的方法
}
}
}
注意
1.局部内部类的使用离不开方法,所有要想得到局部内部类对象必须在方法内调用
2.局部内部类中如果想使用方法内的局部变量,那么该变量必须为final,形参也适用
在JDK1.8之后,默认在形参和局部变量之前添加final关键
package demo2;
import java.io.Serializable;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午9:16:15 package demo; public class Out{ } 类说明
*/
public class Out {
//外部类的成员变量
int a=10;
//外部类的成员方法
public void fun( int d) {
final int b=5;//局部变量
System.out.println("外部类的成员方法");
class In{
int c=15;
public void fun(){
//d=15;//报错,因为局部变量和形参前默认添加final关键字,不能二次赋值
//b=15;
System.out.println(b);
System.out.println("局部内部类的成员方法");
}
}
//访问局部内部类对象必须要在方法内访问
In in=new In();
in.fun();
}
}
package demo2;
/**
* @author Eric 15665627080@163.com
* @date 2019年8月8日
* @time 上午10:23:43
* package demo2;
* public class Test{ }
* 类说明
*/
public class Test {
public static void main(String[] args) {
Out out=new Out();
out.fun(5);
}
}
匿名内部类
对于一些不能new出来的类和接口,其new出来的就叫匿名内部类,安卓和中间件大量使用
语法
public interface Aa{
//抽象方法
}
Aa aa=new Aa(){
//抽象方法的具体实现
};
注意
1.匿名内部类的操作对象是接口和抽象类
2.接口和抽象类中的抽象方法必须在匿名内部类中具体实现;
3.如果在方法内部使用匿名内部类,如果匿名内部类中使用到了方法的形参和局部变量,那么该形参和局部变量必须要被final所修饰
匿名内部类new出来的是接口,是为了减少代码冗余(少new一个实现接口的子类)
在安卓中如果遇到一个方法的内部使用到了匿名内部类,那么匿名内部类中使用到的形参必须被final所修饰
实战案例:
写一个接口,有一个求正方形面积的方法,然后使用匿名内部类来调用方法
public interface Area{
public int square(int a);
}
public static void main(String[] args) {
Area a = new Area() {
@Override
public int square(int a) {
return a*a;
}
};
int square = a.square(5);
System.out.println(square);
}