Java面向对象——内部类
5.8内部类
5.8.1内部类的定义
- 定义在类中的类称为内部类,内部类可以更好的阐述内部类和外部类的从属关系,更加满足符合面向对象
5.8.2内部类的分类
- 内部类分为四种:
- 普通内部类
- 静态内部类
- 局部内部类
- 匿名内部类
i.普通内部类
代码演示:
package com.pxcoder.myproject4;
//外部类
public class Test02 {
int num=10;
public static void main(String[] args) {
}
public void fun() {
System.out.println("我是普通外部类方法");
}
//普通内部类
class inner02{
String innername="小明";
public inner02() {
}
public void method() {
System.out.println("我是普通内部类方法");
}
}
}
定义:
- 普通内部类无法定义静态内容。是作为外部类的一个成员存在的,可以通过4种权限修饰符修饰。当内部类私有之后只是用来服务于当前外部类的。
(1)外部类使用内部类
代码演示:
package com.pxcoder.myproject4;
public class Test02 {
int num=10;
public static void main(String[] args) {
Test02 b=new Test02();
b.fun();
}
public void fun() {
System.out.println("我是普通外部类方法");
//创建内部类对象来调用内部类中的方法和属性
inner02 a=new inner02();
a.method();
System.out.println(a.innername);
}
class inner02{
String innername="小明";
public inner02() {
}
public void method() {
System.out.println("我是普通内部类方法");
}
}
}
- 外部类使用内部类中成员内容(成员方法和成员属性)直接创建对象即可调用
- 在外部类的静态方法中无法闯将内部类的对象
(2)内部类使用外部类
代码演示:
package com.pxcoder.myproject4;
public class Test02 {
int num=10;
public static void main(String[] args) {
Test02 b=new Test02();
b.fun();
}
public void fun() {
System.out.println("我是普通外部类方法");
inner02 a=new inner02();
a.method();
System.out.println(a.innername);
}
class inner02{
String innername="小明";
public inner02() {
}
public void method() {
System.out.println("我是普通内部类方法");
System.out.println(num);
System.out.println(Test02.this.num);
}
}
}
//执行结果:
我是普通外部类方法
我是普通内部类方法
10
10
小明
- 内部类访问外部类的成员内容(成员方法和成员属性)直接通过变量名或者是方法名直接调用即可
- 内部类中持有了外部类的引用:外部类.this。外部类.this代指的是外部类的当前对象。
- 内部类调用外部类的静态内容时,直接通过静态变量名或者是静态方法名直接调用即可。
(3)其他类访问内部类
代码演示:
//方法一
package com.pxcoder.myproject4;
//导包
import com.pxcoder.myproject4.Test02.inner02;
public class Test002 {
public static void main(String[] args) {
inner02 in=new Test02().new inner02();
in.method();
}
}
//方法二
package com.pxcoder.myproject4;
//导包
import com.pxcoder.myproject4.Test02.inner02;
public class Test002 {
public static void main(String[] args) {
Test02.inner02 in=new Test02().new inner02();
in.method();
}
}
package com.pxcoder.myproject4;
//外部类
public class Test02 {
int num=10;
public void fun() {
System.out.println("我是普通外部类方法");
}
//内部类
class inner02{
String innername="小明";
public inner02() {
}
public void method() {
System.out.println("我是普通内部类方法");
System.out.println(num);
}
}
}
- 其他类访问内部类的成员,需要创建内部类对象。
- 由于内部类从属于外部类,所以在创建对象时需要指定内部类的所属。
- 内部类变量名= new外部类().new内部类();注意这里一定要导包
- 外部类.内部类变量名= new外部类().new内部类();注意这里可能要导包
tips:对于内部类而言,编译之后的源文件的class文件为:外部类$内部类.class
ii.静态内部类
代码演示:
package com.pxcoder.myproject4;
//外部类
public class Test02 {
int num=10;
public static void main(String[] args) {
}
public void fun() {
System.out.println("我是普通外部类方法");
}
//静态内部类
static class inner02{
String innername="小明";
public inner02() {
}
public void method() {
System.out.println("我是静态内部类方法");
}
public static void method1() {
System.out.println("我是静态内部类的静态方法");
}
}
}
定义;
- 声明在类中,并且通过static修饰的类称之为静态内部类
- 和普通内部类相比,静态内部类中可以声明静态内容
- 静态内部类相当于外部类的一个静态方法
(1)外部类使用内部类
代码演示:
package com.pxcoder.myproject4;
public class Test02 {
int num=10;
public static void main(String[] args) {
Test02 b=new Test02();
b.fun();
}
public void fun() {
System.out.println("我是普通外部类方法");
//创建对象访问静态内部类中的非静态的成员
inner02 a=new inner02();
a.method();
System.out.println(a.innername);
//直接访问静态内部类的静态成员
inner02.method1();
System.out.println(inner02.age);
}
static class inner02{
String innername="小明";
static int age=23;
public inner02() {
}
public void method() {
System.out.println("我是静态内部类方法");
}
public static void method1() {
System.out.println("我是静态内部类的静态方法");
}
}
}
- 外部类使用内部类的非静态内容,创建对象访问
- 外部类使用内部类的静态内容,通过
类名.属性/方法名
访问。
(2)内部类使用外部类
代码演示:
package com.pxcoder.myproject4;
import org.omg.CORBA.PUBLIC_MEMBER;
public class Test02 {
int num=10;
public static void main(String[] args) {
Test02 b=new Test02();
b.fun();
}
public void fun() {
System.out.println("我是普通外部类方法");
//创建对象访问静态内部类中的非静态的成员
inner02 a=new inner02();
a.method();
//直接访问静态内部类的静态成员
inner02.method1();
}
public void mage() {
System.out.println("我是外部类的方法");
}
static class inner02{
String innername="小明";
static int age=23;
public inner02() {
}
public void method() {
System.out.println("我是静态内部类方法");
//创建外部类对象来访问外部类的成员
Test02 b=new Test02();
b.mage();
b.num;
}
public static void method1() {
System.out.println("我是静态内部类的静态方法");
Test02 b=new Test02();
b.mage();
}
}
}
- 内部类访问外部类中的属性以及方法都需要创建对象访问。
(3)其他类访问内部类
代码演示:
package com.pxcoder.myproject4;
//导包
import com.pxcoder.myproject4.Test02.inner02;
public class Test002 {
public static void main(String[] args) {
//访问静态内部类的静态成员
System.out.println(inner02.age);
inner02.method1();
Test02.inner02.method1();
//访问静态内部类的非静态成员
inner02 on=new inner02();
on.method();
inner02 in=new Test02.inner02();
in.method();
}
}
package com.pxcoder.myproject4;
//外部类
public class Test02 {
int num=10;
public void fun() {
System.out.println("我是普通外部类方法");
}
public void mage() {
System.out.println("我是外部类的方法");
}
//静态内部类
static class inner02{
String innername="小明";
static int age=23;
public inner02() {
}
public void method() {
System.out.println("我是静态内部类方法");
}
public static void method1() {
System.out.println("我是静态内部类的静态方法");
}
}
}
- 访问非静态内容,需要创建对象,创建对象时
- 外部类.内部类 变量名= new外部类.内部类() ;【不需要导包测试类和外部类同包】
- 内部类 变量名= new 外部类.内部类() ;【需要导包】
- 内部类 变量名=new 内部类();【需要导包】
- 访问静态内容
- 内部类.静态内容【需要导包】
- 外部类.内部类.静态内容【不需要 导包测试类和外部类同包】
iii.局部内部类
- 局部内部类定义在方法中的类
代码演示:
package com.pxcoder.myproject4;
//外部类
public class Test03 {
public static void main(String[] args) {
method();
}
public static void method() {
//局部内部类
class inner03{
int age;
public void mage() {
System.out.println("我是一个局部内部类方法");
}
}
//创建局部内部类的对象调用局部内部类的成员
inner03 a=new inner03();
a.mage();
System.out.println(a.age);
}
}
- 局部内部类中类的修饰符只能通过abstract、final修饰
- 局部内部中定义的方法值只能非静态方法。
- 局部内部类只能够让当前方法使用。
- 局部内部类是针对方法的个性化定制,而且减少了内存使用
vi.匿名内部类
- 匿名对象是只能使用一次,同理匿名内部类也只能使用一次。JDK1.8中关于Lambda表达式的书写规则。
package com.pxcoder.myproject3;
//统一接口
public interface Filter1 {
public abstract void filter(Student[] stus);
}
package com.pxcoder.myproject3;
public class Student {
private int id;
private String name;
private int age;
private int score;
public Student() {
}
public Student(int id,String name,int age,int score) {
this.id=id;
this.name=name;
this.age=age;
this.score=score;
}
public void setScore(int score) {
this.score=score;
}
public int getScore() {
return score;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return age;
}
public String toString() {
return name+" "+id+" "+age+" "+score;
}
}
package com.pxcoder.myproject3;
public class Demo02{
public static void main(String[] args) {
//声明一个学生数组,存放5个学生信息
Student stu1=new Student(1,"张山",12,60);
Student stu2=new Student(2,"张三",15,66);
Student stu3=new Student(3,"李四",34,70);
Student stu4=new Student(4,"小二",49,80);
Student stu5=new Student(5,"王二",18,90);
//声明一个学生数组 存储学生对象
Student[] stus=new Student[] {stu1,stu2,stu3,stu4,stu5};
//匿名内部类使用,接口不可以实例化
filter(new Filter1(){
@Override
public void filter(Student[] stus){
for(Student stu:stus){
if(stu.getAge()>20&&stu.getAge()<50){
System.out.println(stu+",");}
}
}
},stus);
}
public static void filter(Filter1 filter,Student[] stus) {
//Filter filter = new AgeFilter()
filter.filter(stus);//多态
}
}
//执行结果:
李四 3 34 70,
小二 4 49 80,
关于Lambda表达式:
public class Test03{
public static void main(String[] args){
//方法一
MyRun r=new MyRun();
new Thread(r);
//方法二
new Thread(new Runnable(){
public voidrun(){
System.out.println("匿名內部類");
}
});
//方法三
new Thread(()->{System.out.println("匿名內部類");});
}
}
class MyRun implements Runnable{
@Override
public void run(){
System.out.println("myrun");
}
}