一,内部类
1,定义:
在一个类内部定义的类就叫做内部类。
2,分类
成员内部类:在class内部,成员变量和方法外部。
局部内部类:在某个方法内部编写(重点)。
class T{
class B{} //成员内部类
int a=10;
public void test(){
class D{} //局部内部类
}
}
二,成员内部类
1,成员内部类就是外部类的一个成员,和成员变量、成员方法同级别。
2,在成员内部类的内部可以直接用外部类的成员,包括可以直接使用外部类的私有成员。
3,内部类的使用方法:
第一种:是借助外部类的成员来间接调用内部类(重要)。
第二种通过语法调用:
语法:(内部类对象在使用之间必须先存在外部类对象)
外部类名称 . 内部类名称 对象名称=new 外部类名称() . new 内部类名称();
4,内部类常见的修饰符
private: 是内部类常见的修饰符
被private修饰的内部类只是一种使用方式,就是通过外部成员间接调用。
static:
被static修饰的内部类,属于外部类的静态成员,只能调用外部类的静态成员。
第一种使用方式:可以通过外部类的成员间接调用。
第二种使用方式:
语法:外部类名称 . 内部类名称 对象名称=new 外部类名称 . 内部类名称();
class T2{
int a=10;
static int d=30
private int c=40;
public void test(){
System.out.println("外部类成员方法");
}
private class A2{
int b=20;
public void test1(){
System.out.println("内部类成员方法1");
System.out.println("a="+a);
this();
}
}
public void testInner(){
A2 aa=new A2();
aa.test1();
}
static class A3{
int b=20;
public void test2(){
System.out.println("内部类成员方法2");
//System.out.println("a="+a);//a是外部类的非静态成员变量,不能调用。
//test();//test是外部类的非静态成员方法,不能调用
System.out.println("d="+d);//d是外部类的静态成员变量,可以调用。
}
}
public void testStaticInner(){
A3 a3=new A3();
a3.test2();
}
}
public class InnerClassDemo{
public static void main(String[] args){
//普通内部类的第一种使用方式,通过外部类的成员间接调用内部类
T2 tt=new T2();
tt . testInner();
//普通内部类的第二种使用方式,通过语法直接创建内部类对象
//T2 . A2 xx=new T2() . new A2();
//A2被private修饰之后,不能再使用这种方式调用。
//xx.test1();
//第一种:static修饰的内部类,通过外部类的成员间接调用内部类
T2 yy=new T2();
yy.testStaticInner();
第二种:被static修饰的,通过语法直接调用静态内部类
T2 . A3 ee=new T2 . A3();
ee.test2();
}
}
三,局部内部类
1,局部内部类可以直接调用外部类成员,包括私有成员。
2,局部内部类的使用方式,只能在其所在的方法内部被调用。
3,局部内部类中使用局部变量,这个被使用的局部变量必须是常量。(重点)
以上的规定如何解释?(重点)
局部内部类创建的对象在堆内存,而局部变量是在栈内存,是随着方法的执行而创建,随着
方法的执行完毕而消失。但是在堆内存的内部类的对象不一定被回收。此时就可能发生了对象
引用了一个已经不存在的变量,就出现问题了。所以java中通过语法控制避免了此问题的发生。
class T3{
int a=10;
private int b=20;
public void test(){
System.out.println("外部类成员方法test");
}
public void test1(){
class B2{
public void test2(){
System.out.println("a="+a);
test();
System.out.println("b="+b);
}
}
B2 bb=new B2();
bb.test2();
}
public void test3(){
final int i=50;
class B3{
public void speak(){
System.out.println("局部类B3的speak方法");
System.out.println("i="+i);//i是常量,则在编译期就把"i="+i变成"i=50",所以执行时不会出现问题。
}
}
B3 b3=new B3();
b3.speak();
}
}
public class InnerClassDemo2{
public static void main(String[] args){
//创建T3外部类对象
T3 t3=new T3();
t3 . test1();
}
}
四,匿名内部类
interface I1{
void test1();
void test2();
}
class E1{
public void print1(){
//以下代码创建了一个没有名称的内部类,它实现了I1接口并创建了这个没有名称的内部类的一个对象
//然后可以调用这个对象的test1方法
new(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
}.test(); //(这是匿名内部类的语法)
}
//匿名内部类常见使用方式:做方法参数会在方法返回值
public void print2( I1 ii){
ii.test1();
}
//匿名内部类做返回值
public void print3(){
return new I1(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
public void test2(){
System.out.println("对接口I1的test2方法重写");
}
};
}
}
public class InnerClassDemo3{
public static void main(String[] args){
E1 ee=new E1();
ee.print1();
//使用匿名内部类的方式调用e1对象的print3方法
E1 e1=new E1();
e1.print2(new I1(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
public void test2(){
System.out.println("对接口I1的test2方法重写");
}
});
}
}
一,内部类
1,定义:
在一个类内部定义的类就叫做内部类。
2,分类
成员内部类:在class内部,成员变量和方法外部。
局部内部类:在某个方法内部编写(重点)。
class T{
class B{} //成员内部类
int a=10;
public void test(){
class D{} //局部内部类
}
}
二,成员内部类
1,成员内部类就是外部类的一个成员,和成员变量、成员方法同级别。
2,在成员内部类的内部可以直接用外部类的成员,包括可以直接使用外部类的私有成员。
3,内部类的使用方法:
第一种:是借助外部类的成员来间接调用内部类(重要)。
第二种通过语法调用:
语法:(内部类对象在使用之间必须先存在外部类对象)
外部类名称 . 内部类名称 对象名称=new 外部类名称() . new 内部类名称();
4,内部类常见的修饰符
private: 是内部类常见的修饰符
被private修饰的内部类只是一种使用方式,就是通过外部成员间接调用。
static:
被static修饰的内部类,属于外部类的静态成员,只能调用外部类的静态成员。
第一种使用方式:可以通过外部类的成员间接调用。
第二种使用方式:
语法:外部类名称 . 内部类名称 对象名称=new 外部类名称 . 内部类名称();
class T2{
int a=10;
static int d=30
private int c=40;
public void test(){
System.out.println("外部类成员方法");
}
private class A2{
int b=20;
public void test1(){
System.out.println("内部类成员方法1");
System.out.println("a="+a);
this();
}
}
public void testInner(){
A2 aa=new A2();
aa.test1();
}
static class A3{
int b=20;
public void test2(){
System.out.println("内部类成员方法2");
//System.out.println("a="+a);//a是外部类的非静态成员变量,不能调用。
//test();//test是外部类的非静态成员方法,不能调用
System.out.println("d="+d);//d是外部类的静态成员变量,可以调用。
}
}
public void testStaticInner(){
A3 a3=new A3();
a3.test2();
}
}
public class InnerClassDemo{
public static void main(String[] args){
//普通内部类的第一种使用方式,通过外部类的成员间接调用内部类
T2 tt=new T2();
tt . testInner();
//普通内部类的第二种使用方式,通过语法直接创建内部类对象
//T2 . A2 xx=new T2() . new A2();
//A2被private修饰之后,不能再使用这种方式调用。
//xx.test1();
//第一种:static修饰的内部类,通过外部类的成员间接调用内部类
T2 yy=new T2();
yy.testStaticInner();
第二种:被static修饰的,通过语法直接调用静态内部类
T2 . A3 ee=new T2 . A3();
ee.test2();
}
}
三,局部内部类
1,局部内部类可以直接调用外部类成员,包括私有成员。
2,局部内部类的使用方式,只能在其所在的方法内部被调用。
3,局部内部类中使用局部变量,这个被使用的局部变量必须是常量。(重点)
以上的规定如何解释?(重点)
局部内部类创建的对象在堆内存,而局部变量是在栈内存,是随着方法的执行而创建,随着
方法的执行完毕而消失。但是在堆内存的内部类的对象不一定被回收。此时就可能发生了对象
引用了一个已经不存在的变量,就出现问题了。所以java中通过语法控制避免了此问题的发生。
class T3{
int a=10;
private int b=20;
public void test(){
System.out.println("外部类成员方法test");
}
public void test1(){
class B2{
public void test2(){
System.out.println("a="+a);
test();
System.out.println("b="+b);
}
}
B2 bb=new B2();
bb.test2();
}
public void test3(){
final int i=50;
class B3{
public void speak(){
System.out.println("局部类B3的speak方法");
System.out.println("i="+i);//i是常量,则在编译期就把"i="+i变成"i=50",所以执行时不会出现问题。
}
}
B3 b3=new B3();
b3.speak();
}
}
public class InnerClassDemo2{
public static void main(String[] args){
//创建T3外部类对象
T3 t3=new T3();
t3 . test1();
}
}
四,匿名内部类
interface I1{
void test1();
void test2();
}
class E1{
public void print1(){
//以下代码创建了一个没有名称的内部类,它实现了I1接口并创建了这个没有名称的内部类的一个对象
//然后可以调用这个对象的test1方法
new(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
}.test(); //(这是匿名内部类的语法)
}
//匿名内部类常见使用方式:做方法参数会在方法返回值
public void print2( I1 ii){
ii.test1();
}
//匿名内部类做返回值
public void print3(){
return new I1(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
public void test2(){
System.out.println("对接口I1的test2方法重写");
}
};
}
}
public class InnerClassDemo3{
public static void main(String[] args){
E1 ee=new E1();
ee.print1();
//使用匿名内部类的方式调用e1对象的print3方法
E1 e1=new E1();
e1.print2(new I1(){
public void test1(){
System.out.println("对接口I1的test1方法重写");
}
public void test2(){
System.out.println("对接口I1的test2方法重写");
}
});
}
}