定义
将一个类的定义置入另一个类的定义中,这个类就是内部类。
嵌套在另外的一个类中,和外部类的属性使用方式差不多。
public class Out {
int i = 10;
class Inner1{
public void show(){
System.out.println("this is Inner1!");
}
}
public class Inner2{
public Inner2() {}
public Inner2(String desc){
System.out.println(desc);
System.out.println(i);
}
}
public void show(){
Inner1 inner1 = new Inner1();
Inner2 inner2 = new Inner2("inner2");
inner1.show();
System.out.println("Out's method!");
}
public static void main(String[] args) {
Out out = new Out();
out.show();
}
}
方法和作用域中的内部类
目的
实现某种形式的接口,使自己能够创建和返回一个句柄
解决复杂问题的时候,希望创建一个类并辅助自己的程序方案,同时不愿意公开。
- 在一个方法中定义,作用域在这个方法内
/**
2. 定义在方法中的内部类实现了Shape接口,其作用域在整个方法
3. @author lenovo
4. */
public class Out {
public void show(){
class Circle implements Shape{
public void show(double r) {
System.out.println("这是一个半径为"+r+"的圆!");
}
}
// Scanner in = new Scanner(System.in);
// double r = in.nextDouble();
Shape shape = new Circle();
shape.show(3.33);
}
public static void main(String[] args) {
Out out = new Out();
out.show();
}
}
- 在方法的作用域定义
/**
1. 定义一个用于测试作用域区间的内部类,范围介于花括号之间
2. 虽然类是在作用域中,但是类并不是根据条件创建的,是随其他一起得到编译的。
3. 并且除了作用范围在花括号间,它和普通的类没什么区别
4. @author lenovo
5. */
public class Out2 {
public void ceshi(boolean flag){
if(flag){
class Inner{
public void show(){
System.out.println("用于测试用例!");
}
}
Inner inner = new Inner();
inner.show();
}
}
public static void main(String[] args) {
Out2 out2 = new Out2();
out2.ceshi(true);
}
}
3.一个匿名类,实现一个接口
/**
* 一个匿名的内部类,必须继承抽象类或者实现接口,并且会自动的向上转型
* @author lenovo
*
*/
public class Out3 {
public Shape shape(){
return new Shape() {
//
@Override
public void show(double r) {
// TODO Auto-generated method stub
tt();
}
public void tt(){
System.out.println("nihao");
}
};
}
public static void main(String[] args) {
Out3 out3 = new Out3();
Shape shape = out3.shape();
shape.show(3);
}
}
4.扩展拥有非默认构造器的类
public class Warp {
int i;
public Warp(int i){
this.i = i;
}
public int value(){
return i;
}
}
/**
* 一个普通的基础类
* 基础类只有带参的构造方法,使用匿名类继承这个基础类
* @author lenovo
*
*/
public class Test {
public Warp warp(int x){
return new Warp(x){
public int value(){
return super.value()*10;
}
};
}
public static void main(String[] args) {
Test test = new Test();
Warp warp = test.warp(2);
int n = warp.value();
System.out.println(n);
}
}
结果:20
5.如果想要在匿名内部类中使用某个参数,这个参数必须是final的
/**
*匿名内部类中使用外部的参数
/
public class Ceshi2 {
public Warp warp(final int x){
return new Warp(x){
int n = x;
public int value(){
System.out.println(n);
return super.value()*10;
}
};
}
}
**内部类非常重要的一点:拥有对封装类的所有的访问权限
5.如何在别的类中创建一个内部类对象
首先创建外部类的对象
利用外部类的对象创建内部类的对象
Out out = new out();
Out.Inner inner = out.new Inner();
6.静态内部类
牢记一点:内部类的对象默认持有创建它的 封装类的对象;不能从一个static内部类对象访问一个外部类;好比是普通的内部类是外部类的属性,和对象挂钩,静态内部类则是不需要外部类的对象也能访问。
7.从内部类中继承
继承必需要有外部类的句柄进行初始化
/**
* 从一个内部类中继承,那么进行实例化必须采用一种特殊的语法来明确这种关系
* @author lenovo
*
*/
public class ExtendsInner extends WithInner.Inner {
public ExtendsInner(WithInner wi) {
wi.super();
}
public static void main(String[] args) {
WithInner withInner = new WithInner();
ExtendsInner ei = new ExtendsInner(withInner);
ei.show();
}
}