JAVA面向对象四 内部内部类和lambda

JAVA面向对象四 内部内部类和lambda

面向对象马上也要进入尾声了,今天我们来学习下面向对象的最后部分,内部类和lamda。虽然我们可能会对面向只有一个模模糊糊的印象的,但我们只要多看多练,总会一层层揭开它神秘的面纱的。

内部类

内部类就是在类中在写一个类,根据所写类的位置和修饰,我们可以分为成员内部类,静态内部类,私有内部类,局部内部类,匿名内部类。相对来讲,匿名内部类是更重要一些的。

成员内部类

内部类作为外部类的成员,就称为成员内部类
成员内部类既有成员的特点,又有类的特点
可以成员修饰符进行修饰: 权限修饰符 static final.
类可以继承,实现…

定义:成员内部类中 除了静态常量,其他的静态内容不能定义。

使用:在成员内部类中可以直接使用外部类中的成员,包括私有的
使用内部类中的成员要通过内部类对象使用,包含私有的
其他类中使用内部类中的成员,需要**通过外部类对象构建内部类对象,**使用内部类的成员

成员内部类可以直接使用外部类的成员,而外部类使用内部类的成员是需要调用内部类的对象的,如果是其他类,则需要通过调用外部类的对象构建内部对象使用。

public class Outer01 {
    //类中方法外->成员
    public int i = 1;
    private int j = 11;

    //成员内部类
    class Inner extends A{
        //静态常量
        static final int A = 5;
        public int b = 15;
        private int c = 20;

        //成员方法
        public void inner(){
            System.out.println(i);
            System.out.println(j);
        }
    }

    //外部类的成员方法
    public void outter(){
        System.out.println(Inner.A);
        //使用内部类中的成员要通过内部类对象使用
        Inner in = new Inner();
        System.out.println(in.b);
        System.out.println(in.c);
        in.inner();
    }
}    

私有内部类

在私有内部 类中可以直接使用外部类的成员,包含私有
在外部类中可以通过私有内部类的对象直接使用私有内部类的成员,包含私有
其他类中无法使用私有内部类
可以间接使用私有内部类中的私有成员,可以作为外部类方法的参数返回

public class Outer03 {
    //私有成员变量
    private int i = 1;

    //私有内部类
    private class Inner{
        //私有内部类的私有成员
        private String a = "私有内部类的私有成员";

        private void inner(){
            System.out.println(i);
        }
    }

    public String outer(){
        Inner in = new Inner();
        System.out.println(in.a);
        in.inner();

        return in.a;
    }
}

静态内部类

静态内部类中定义静态内容,可以定义成员

在内部类中可以直接使用外部类中静态的内容,

如果想要使用外部类中成员的内容,通过外部类对象使用

(静态的可以直接调用静态的;静态调用成员需要构建对象才能调用。静态内部类也是一样的;)

public class Outer04 {
    //静态变量
    static int i = 1;
    //成员变量
    int j = 10;

    //静态内部类
    static class Inner{
        static String a = "静态内部类中的静态变量a";
        String b = "静态内部类中的成员变量b";

        static void testStatic(){
            System.out.println("静态内部类中的静态方法");

            System.out.println(a);
            System.out.println(new Inner().b);

            System.out.println(i);
            System.out.println(new Outer04().j);

        }

        void test(){
            System.out.println("静态内部类中的成员方法");

            System.out.println(i);
            System.out.println(new Outer04().j);
            System.out.println(a);
            System.out.println(b);
        }
    }
}

局部内部类

只能在所定义的方法中使用
如果局部内部类中使用所在方法的参数,默认被final修饰

​ (java7手动添加final,java8之后默认final)

public class Outer05 {
    static int a = 123;

    public static void main(String[] args) {
        //调用局部内部类,因为是在方法中的,需要调用outer方法
        //静态方法调用局部方法需要构建对象,这边就创建Outer05的对象调用
        Outer05 n = new Outer05();
        n.outer(5);

    }

    void outer(final int args){
        //局部
        int i =1;


        //局部内部类
        class Inner{
            //局部内部类成员变量
            String str = "局部内部类成员变量";

            void  inner(){
                System.out.println(i);
                System.out.println(a);
                System.out.println(args);
            }
        }

        Inner in = new Inner();
        System.out.println(in.str);
        in.inner();
		//args 作为局部内部类方法的参数,相当于被final修饰,不可以被改变
        //args = 100;
    }
}

匿名内部类

没有名字的内部类

public class Anonymous{
    public static void main(String[] args) {
        //第一种:只在当前行使用一次,后续无法继续使用
        new Run(){

            @Override
            public void run() {
                System.out.println("running");
            }
        }.run();
        //第二种:引用指向匿名内部类对象,后续可以多次使用
        Swim swim=new Swim(){

            @Override
            public void swimming() {
                System.out.println("free swim");
            }

            @Override
            public void drinking() {
                System.out.println("drink water");

            }
        };
        swim.drinking();
        swim.swimming();
        //第三种 匿名内部类做参数传递  调用方法
        test(new Swim() {
            @Override
            public void swimming() {
                System.out.println("free  ~~~");
            }

            @Override
            public void drinking() {
                System.out.println("~~~~");
            }
        });
    }
	//一个静态带参的方法
    static void test(Swim swim) {
		swim.swimming();
        swim.drinking();
    }
}
//Run 接口 
interface Run{
    void run();
}
//Swim接口
interface  Swim{
    void swimming();
    void drinking();
}

使用: 1>只在当前行使用一次,后续无法继续使用

//原本是需要创建一个类来实现对象的
class Tiger implements Run{
    
    //重写接口的方法
    @Override
    public void run() {
        System.out.println("running");
    }
    public static void main(String[] args) {
    //运用接口的多态 所有有Run的对象
    Run r=new Tiger();
    r.run();
    //现在如果只用run方法一次,不想要创建Tiger类,就可以用匿名了,直接用Run的对象
    /*
    new Run(){
    //重写Run接口的方法
    @Override
    public void run() {                      
        System.out.println("running");
    }.run; //.run就是用run方法
    
    } 
    */    
    }

}
    

​ 2>引用指向匿名内部类对象,后续可以多次使用

​ 和第一种其实是一样的,就是加了一个变量接收第一种,这样就可以多次使用了。

    //引用指向匿名内部类对象,后续可以多次使用
    Run r =new Run(){
    	//重写Run接口的方法
    	@Override
    	public void run() {                      
       		System.out.println("running");
        }
    }; 
        r.run;    
    
     

如果只有一个接口方法的话,效果不是很明显,当有多个(可以看匿名内部类开始的代码)会非常便利,也提高了代码的复用性。

​ 3>匿名内部类做参数传递

// 先写一个方法,然后直接调用使用一个带参的方法
/*test(第一种);
-------------------
test(new Run(){
    //重写Run接口的方法
    @Override
    public void run() {                      
        System.out.println("running");
    });
*/

lambda

目的: 为了简化大量使用匿名内部类,可以java8提供的lambda表达式简化

前提: 函数型接口
函数型接口: 只要一个必须要被重写的抽象方法的接口
检查函数型接口的注解: @FunctionalInterface

语法:()->{}
(): 重写的抽象方法的参数列表
->: lambda符号,箭头符号
{}: 重写抽象方法的方法体{}

注意:
lambda体重写哪一个接口的抽象方法,看前面的引用

public static void main(String[] args) {
        //匿名内部类
        Run s = new Run() {
            @Override
            public void run() {
                System.out.println("running");
            }
        }; 
		//1.简化匿名内部类
        //s是 Run s的,因为前面有定义Run s = new Run(){},所以这里没有写
    
        s = ()->{
            System.out.println("running。。。");
        };

        s.run();
        //2.如果lambda中的方法体{}中语句体只有一句,前后的{}可以省略
    	//注意需要定义interface A的
        A demo = ()->System.out.println("123");

        //3.如果抽象方法的有形参,参数的数据类型可以省略
    	//注意需要定义interface B的
        B demo = (x,y)-> System.out.println(x+y);

        //4.如果抽象方法的有形参,并且参数只有一个,前后()可以省略
    	//注意需要定义interface C的
        C demo = i-> System.out.println(i);

        //5.如果语句体只有一句,并且是return语句
        //注意需要定义interface D的
        D demo = i-> {
            return i>100;
        };

到现在面向对象基本是结束了,但这也只是一些基础的语法点,要想熟练运用还有很长的路要走……一定要一直向前,不能停下前进的脚步。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值