2021-05-15

本文详细介绍了Java中的内部类,包括成员内部类、静态内部类、局部内部类和匿名内部类的定义、访问权限及使用场景。通过示例代码展示了如何在不同情况下创建和使用内部类,强调了内部类在数据安全性、代码复用和抽象封装等方面的优势。同时,讨论了匿名内部类在实现接口和抽象类时的便捷性。
摘要由CSDN通过智能技术生成

内部类的定义

在Java的类中可以定义一个内部类

就是在"A类"中定义一个"B类"

类B是类A的内部类

类A是类B的外部类

内部类的成员是可以访问外部类的成员,私有也可以访问

//外部类
class Outer{

    public int num = 10 ;
    private int num2 =100 ;

    //class Outer的内部类
    class Inner{
        //成员方法
        public void show(){
            System.out.println(num);
            System.out.println(num2);
        }
    }
    //外部类的成员方法
    public void method(){
        //show() ;
        Inner inner = new Inner() ;
        inner.show();
    }
}

//测试类
public class OuterDemo {
    public static void main(String[] args) {
        //创建外部类对象
        Outer outer = new Outer() ;
        outer.method();



    }

}

成员内部类:

 在一个类的成员位置中定义的类
 
                 需求:测试类中直接访问成员内部类的成员方法:
 
                 访问的方式:
                       外部类名.内部类名 对象名  = 外部类对象.内部类对象;

                       前提条件:这个成员内部类---是一个非静态的成员内部类!

//外部类
 class Outer3{
        //成员变量
    private int num = 100 ;

    private static int num2 = 20 ;

    //定义成员内部类
    class Inner3{
        //成员方法
        public void show(){
            System.out.println(num);
            System.out.println(num2);
        }
    }
}
//测试类
public class OuterDemo3 {
    public static void main(String[] args) {

        //    外部类名.内部类名 对象名  = 外部类对象.内部类对象;
        Outer3.Inner3 oi = new Outer3().new Inner3() ;
        oi.show() ;
    }
}

 

内部类的访问:

 成员内部类可以被private修饰---保证数据的安全性:让外界不能new 来访问!


 成员内部类也可以被static修饰:
      它里面的成员访问外部类的成员特点:此时外部类的成员必须都是静态的

     外界类中要访问静态的成员内部类的成员方法:
                  需要将静态的成员内部类---->看成是外部类的静态成员
                  外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
 
         非静态的成员内部类中,不能存在静态的成员---"冲突了"

public class Test1 {//外部类
    private int sum = 10;
    public static int sum1 = 20;

     static class inner2{//静态的内部类

        public void show(){
            System.out.println(sum1);
            //System.out.println(sum);静态成员无法访问非静态外部类的非静态变量
        }

    public static void show2(){//静态的成员方法
        System.out.println(sum1);
    }
}
}
class Testt{
    public static void main(String[] args) {
        //外部类名.内部类名 对象名  = 外部类对象.内部类对象;
       // Test1.inner2 tt = new Test1.inner2();     内部类是静态的所以访问不了

        //外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
        Test1.inner2 tt = new Test1.inner2();
        tt.show();
        tt.show2();
    }
}

 

局部内部类:在外部类的成员方法中定义的类,(非静态的)

局部内部类:在外部类的成员方法中定义的类,(非静态的)
         直接可以访问外部类的包括私有
 
 
         局部内部类访问局部变量的时候:
                 此时局部变量已经是常量了:被final修饰
                 jdk7以前:如果局部变量不显示的添加final关键字,编译报错!
                 jdk8版本,对当前局部内部类访问局部变量---此时变量在内存中已经优化为final了,不需要显示添加这个关键字!
 
 
         为什么局部变量:是一个常量呢?
                  当外部类对象调用外部类的成员方法时候,num2随着method的方法调用而存在
 
                   随着method调用完毕,应该消失掉了;但是局部内部类的成员方法还在使用这个num2,所以
                   JVM进行了优化,JDK8以后 这个变量自动回加入final定义,所以这个必须是一个常量,那么内部类才能使用它!
 
外部类跟内部类没有继承关系,不要将内部类的外部类看作父类

//定义一个外部类
class Outer5{

    private int num = 20 ;

    public void method(){
        //局部变量
        int num2 = 50 ;// 常量  --->jdk8以后 :局部内部类访问这个局部变量,可以不书写final,隐藏的!

        //局部内部类
        class Inner5{
            public void show(){
                System.out.println(num);//Outer5.this.num:外部类的this限定
                System.out.println(num2); //常驻内存--"常量池中"
            }
        }

        Inner5 inner5 = new Inner5() ;
        inner5.show();
    }
}

public class OuterDemo5 {
    public static void main(String[] args) {

        //访问Inner5中的show
        //创建外部类对象.调用method
        Outer5 outer5 = new Outer5() ;
        outer5.method();
    }
}

匿名内部类

//什么是匿名内部类:
   // 匿名内部类经常就是在局部位置使用!
   // 格式"

    new 类名/接口名(){
        重写抽象方法{
            ....
        }
   };

//匿名内部类的本质是什么: 继承了该抽象类或实现了该接口的子类对象



//定义一个接口
interface Inter{

//有多个抽象方法:
    void show() ;
    void show2() ;

//定义一个类

class Demo{

    //定义一个方法
    public void method(){

         Inter i = new Inter(){

            @Override
            public void show() {
                System.out.println("show Inter...");
            }

            @Override
            public void show2() {
                System.out.println("show Inter2...");
            }
        } ;

        i.show() ;
        i.show2() ;
    }
}


public class NoNameClassDemo {

    public static void main(String[] args) {
        //创建Demo类对象
        Demo d = new Demo() ;
        d.method();
    }
}

匿名内部类在开发中的使用
方法的形式参数是类(具体类/抽象类),接口

//抽象的人类
abstract  class Person{
    public abstract  void work() ;
}
//定义PersonDemo类
class  PersonDemo{
    public void method(Person p){//抽象类,需要抽象类的子类对象
        p.work();
    }
}
//定义一个子类
class Worker extends  Person{

    @Override
    public void work() {
        System.out.println("工人日日夜夜的coding...");
    }
}

//测试类
public class PersonTest {

    public static void main(String[] args) {
        //需求:访问PersonDemo类中的method方法
        PersonDemo pd = new PersonDemo() ;
        //创建Person类对象---通过子类实例化
        Person p = new Worker();
        pd.method(p);

        System.out.println("-----------------------");

        //方式2:抽象类的匿名内部类
        //需求:访问PersonDemo类中的method方法
        PersonDemo pd2 = new PersonDemo() ;
       
        pd2.method(new Person(){

            @Override
            public void work() {
                System.out.println("工人日日夜夜的coding...");
            }
        });



    }
}


方法的形式参数是接口类型,需要接口的子实现类对象!
也可以使用的接口匿名内部类!

 


interface  Love{
    public abstract void love() ;
}

class LoveDemo{
    public void function(Love love){
        love.love();
    }
}
//定义接口的子实现类
class LoveImpl implements  Love{

    @Override
    public void love() {
        System.out.println("love Java!!!");
    }
}

//测试类中
public class Test2 {
    public static void main(String[] args) {
        //要访问LoveDemo类中的function方法
        //匿名内部类的使用
        LoveDemo ld = new LoveDemo() ;
  
        ld.function(new Love(){

            @Override
            public void love() {
                System.out.println("love javaee...");
            }
        });
        System.out.println("-----------------------------");

        //要访问LoveDemo类中的function方法
        LoveDemo ld2 = new LoveDemo() ;
        Love love = new LoveImpl() ;//接口多态
        ld2.function(love);
    }
}

方法的返回值:引用类型 :抽象类/接口
如果是抽象类,那么返回该抽象类的子类对象

abstract class Person{
    public  abstract void study() ;
}
class StudentDemo{
    public Person method(){

        //不定义具体的子类,使用抽象类的匿名内部类
        return new Person(){

            @Override
            public void study() {
                System.out.println("good good Study,Day Day Up...");
            }
        };
    }
}

//定义一个子类
class Student extends  Person{

    @Override
    public void study() {
        System.out.println("good good Study,Day Day Up...");
    }
}

//测试类
public class Test1 {
    public static void main(String[] args) {
        //访问StudentDemo类中的method方法
        StudentDemo sd = new StudentDemo() ;
        Person person = sd.method(); //匿名内部类的本质:继承了该抽象类的子类对象
        person.study();
    }
}

方法的返回值:引用类型 :接口

interface  Love{
    void love() ;
}
class LoveDemo{
    public Love function(){

        //匿名内部类---接口的匿名内部类
     return   new Love(){

            @Override
            public void love() {
                System.out.println("love JavaEE");
            }
        } ;

        //方式2
       /* Love love = new LoveImpl() ;//子实现类定义了
        return  love ;*/
    }
}

class  LoveImpl implements  Love{

    @Override
    public void love() {
        System.out.println("love Java");
    }
}
//测试类
public class Test2 {
    public static void main(String[] args) {
            LoveDemo ld = new LoveDemo() ;
        Love love = ld.function();
        love.love();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值