Java基础-面向对象进阶

目录

一、案例驱动模式

案例驱动模式的好处 (理解)

二、思想建立

1.分类思想

2.分包思想

3.类与类之间的访问

三、static关键字

1.概述

2.修饰特点

3.static关键字注意事项 (理解)

四、继承

1.继承的实现

2.继承的好处和弊端

3.Java中继承的特点

4.继承中的成员访问特点

①在子类方法中访问一个变量,采用的是就近原则。

②super关键字

③继承中构造方法的访问特点

④父类中没有无参构造方法,只有带参构造方法

5.方法重写

6.权限修饰符

 7.抽象类

五、板块设计模式

1.设计模式

2.模板设计模式

3.模板设计模式的优势

六、final关键字

1.final关键字作用

2.final修饰类、方法、变量的效果

七、代码块

1.代码块分类

2.构造代码块

3.静态代码块

八、接口

1.接口概述

2.接口特点

3.接口成员特点

4.类和接口的关系

5.接口组成更新

默认方法(Java 8)

静态方法(Java 8)

私有方法(Java 9)

    九、多态       

1.多态的前提

2.成员访问特点

3.多态的好处和弊端

4.多态中的转型

5.多态中转型存在的风险和解决方案

十、内部类

1.基本使用

2.成员内部类

3.局部内部类

4.匿名内部类

十一、Lambda表达式

1.函数式编程思想概述

2.Lambda表达式的标准格式

3.Lambda表达式的使用前提

4.Lambda表达式和匿名内部类的区别

5.练习

6.Lambda表达式的省略模式



一、案例驱动模式

通过我们已掌握的知识点,先实现一个案例,然后找出这个案例中,存在的一些问题,在通过新知识点解决问题

案例驱动模式的好处 (理解)

  • 解决重复代码过多的冗余,提高代码的复用性

  • 解决业务逻辑聚集紧密导致的可读性差,提高代码的可读性

  • 解决代码可维护性差,提高代码的维护性

二、思想建立

1.分类思想

分工协作,专人干专事

2.分包思想

如果将所有的类文件都放在同一个包下,不利于管理和后期维护,所以,对于不同功能的类文件,可以放在不同的包下进行管理

包的概述:

  • 本质上就是文件夹

  • 创建包

    多级包之间使用 " . " 进行分割 多级包的定义规范:公司的网站地址翻转(去掉www)

  • 包的命名规则

    字母都是小写

包的注意事项:

  • package语句必须是程序的第一条可执行的代码

  • package语句在一个java文件中只能有一个

  • 如果没有package,默认表示无包名

3.类与类之间的访问

  • 同一个包下的访问

    不需要导包,直接使用即可

  • 不同包下的访问

    1.import 导包后访问

    2.通过全类名(包名 + 类名)访问

  • 注意:import 、package 、class 三个关键字的摆放位置存在顺序关系

    package 必须是程序的第一条可执行的代码

    import 需要写在 package 下面

    class 需要在 import 下面

三、static关键字

1.概述

static 关键字是静态的意思,是Java中的一个修饰符,可以修饰成员方法,成员变量

2.修饰特点

  • 被类的所有对象共享

    是我们判断是否使用静态关键字的条件

  • 随着类的加载而加载,优先于对象存在

    对象需要类被加载后,才能创建

  • 可以通过类名调用

    也可以通过对象名调用

3.static关键字注意事项 (理解)

  • 静态方法只能访问静态的成员

  • 非静态方法可以访问静态的成员,也可以访问非静态的成员

  • 静态方法中是没有this关键字

四、继承

1.继承的实现

  • 继承的概念

    • 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法

  • 实现继承的格式

    • 继承通过extends实现

    • 格式:class 子类 extends 父类 { }

      • 举例:class Dog extends Animal { }

  • 继承带来的好处

    • 继承可以让类与类之间产生关系,子父类关系,产生子父类后,子类则可以使用父类中非私有的成员。

2.继承的好处和弊端

  • 继承好处

    • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)

    • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

  • 继承弊端

    • 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性

  • 继承的应用场景:

    • 使用继承,需要考虑类与类之间是否存在is..a的关系,不能盲目使用继承

      • is..a的关系:谁是谁的一种,例如:老师和学生是人的一种,那人就是父类,学生和老师就是子类

3.Java中继承的特点

  1. Java中类只支持单继承,不支持多继承

    • 错误范例:class A extends B, C { }

  2. Java中类支持多层继承

多层继承:

public class Granddad {

    public void drink() {
        System.out.println("爷爷爱喝酒");
    }

}

public class Father extends Granddad {

    public void smoke() {
        System.out.println("爸爸爱抽烟");
    }

}

public class Mother {

    public void dance() {
        System.out.println("妈妈爱跳舞");
    }

}
public class Son extends Father {
	// 此时,Son类中就同时拥有drink方法以及smoke方法
}

4.继承中的成员访问特点

①在子类方法中访问一个变量,采用的是就近原则。

  1. 子类局部范围找

  2. 子类成员范围找

  3. 父类成员范围找

  4. 如果都没有就报错(不考虑父亲的父亲…)

②super关键字

  • this&super关键字:

    • this:代表本类对象的引用

    • super:代表父类存储空间的标识(可以理解为父类对象引用)

  • this和super的使用分别

    • 成员变量:

      • this.成员变量 - 访问本类成员变量

      • super.成员变量 - 访问父类成员变量

    • 成员方法:

      • this.成员方法 - 访问本类成员方法

      • super.成员方法 - 访问父类成员方法

  • 构造方法:

    • this(…) - 访问本类构造方法

    • super(…) - 访问父类构造方法

  • super内存图:对象在堆内存中,会单独存在一块super区域,用来存放父类的数据

③继承中构造方法的访问特点

注意:子类中所有的构造方法默认都会访问父类中无参的构造方法

子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化,原因在于,每一个子类构造方法的第一条语句默认都是:super()

父类中没有无参构造方法,只有带参构造方法

1. 通过使用super关键字去显示的调用父类的带参构造方法
2. 子类通过this去调用本类的其他构造方法,本类其他构造方法再通过super去手动调用父类的带参的构造方法

注意: this(…)super(…) 必须放在构造方法的第一行有效语句,并且二者不能共存

5.方法重写

  • 1、方法重写概念

    • 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)

  • 2、方法重写的应用场景

    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容

  • 3、Override注解

    • 用来检测当前的方法,是否是重写的方法,起到【校验】的作用

  • 方法重写的注意事项

  1. 私有方法不能被重写(父类私有成员子类是不能继承的)

  2. 子类方法访问权限不能更低(public > 默认 > 私有)

  3. 静态方法不能被重写,如果子类也有相同的方法,并不是重写的父类的方法

public class Fu {
    private void show() {
        System.out.println("Fu中show()方法被调用");
    }

    void method() {
        System.out.println("Fu中method()方法被调用");
    }
}

public class Zi extends Fu {

    /* 编译【出错】,子类不能重写父类私有的方法*/
    @Override
    private void show() {
        System.out.println("Zi中show()方法被调用");
    }
   
    /* 编译【出错】,子类重写父类方法的时候,访问权限需要大于等于父类 */
    @Override
    private void method() {
        System.out.println("Zi中method()方法被调用");
    }

    /* 编译【通过】,子类重写父类方法的时候,访问权限需要大于等于父类 */
    @Override
    public void method() {
        System.out.println("Zi中method()方法被调用");
    }
}

6.权限修饰符

 7.抽象类

在做子类共性功能抽取时,有些方法在父类中并没有具体的体现

一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类

抽象类的特点:

  • 抽象类和抽象方法必须使用 abstract 关键字修饰

    //抽象类的定义
    public abstract class 类名 {}

    //抽象方法的定义
    public abstract void eat();

  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

  • 抽象类不能实例化

  • 抽象类可以有构造方法

  • 抽象类的子类

    要么重写抽象类中的所有抽象方法;要么是抽象类

案例:

  • 案例需求

    定义猫类(Cat)和狗类(Dog)

    猫类成员方法:eat(猫吃鱼)drink(喝水…)

    狗类成员方法:eat(狗吃肉)drink(喝水…)

  • 实现步骤

    1. 猫类和狗类中存在共性内容,应向上抽取出一个动物类(Animal)

    2. 父类Animal中,无法将 eat 方法具体实现描述清楚,所以定义为抽象方法

    3. 抽象方法需要存活在抽象类中,将Animal定义为抽象类

    4. 让 Cat 和 Dog 分别继承 Animal,重写eat方法

    5. 测试类中创建 Cat 和 Dog 对象,调用方法测试

动物类:

public abstract class Animal {
    public void drink(){
        System.out.println("喝水");
    }

    public Animal(){

    }

    public abstract void eat();
}

猫类:

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

狗类:

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}

测试类:

public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();
        d.drink();

        Cat c = new Cat();
        c.drink();
        c.eat();

        //Animal a = new Animal();
        //a.eat();
    }

五、板块设计模式

1.设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

2.模板设计模式

把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法 让使用模板的类(继承抽象类的类)去重写抽象方法实现需求

3.模板设计模式的优势

模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可

代码:
模板类:

/*
    作文模板类
 */
public abstract class CompositionTemplate {

    public final void write(){
        System.out.println("<<我的爸爸>>");

        body();

        System.out.println("啊~ 这就是我的爸爸");

    }

    public abstract void body();
}

实现类A:

public class Tom extends CompositionTemplate {

    @Override
    public void body() {
        System.out.println("那是一个秋天, 风儿那么缠绵,记忆中, " +
                "那天爸爸骑车接我放学回家,我的脚卡在了自行车链当中, 爸爸蹬不动,他就站起来蹬...");
    }
}

实现类B:

public class Tony extends CompositionTemplate {
    @Override
    public void body() {

    }

    /*public void write(){

    }*/
}

测试类:

public class Test {
    public static void main(String[] args) {
        Tom t = new Tom();
        t.write();
    }
}

六、final关键字

1.final关键字作用

final代表最终的意思,可以修饰成员方法,成员变量,类

2.final修饰类、方法、变量的效果

  • fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)

  • final修饰方法:该方法不能被重写

  • final修饰变量:表明该变量是一个常量,不能再次赋值

    • 变量是基本类型,不能改变的是值

    • 变量是引用类型,不能改变的是地址值,但地址里面的内容是可以改变的

public static void main(String[] args){
    final Student s = new Student(23);
  	s = new Student(24);  // 错误
 	s.setAge(24);  // 正确
}

七、代码块

在Java中,使用 { } 括起来的代码被称为代码块

1.代码块分类

局部代码块

  • 位置: 方法中定义

  • 作用: 限定变量的生命周期,及早释放,提高内存利用率

2.构造代码块

  • 位置: 类中方法外定义

  • 特点: 每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行

  • 作用: 将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性

3.静态代码块

  • 位置: 类中方法外定义

  • 特点: 需要通过static关键字修饰,随着类的加载而加载,并且只执行一次

  • 作用: 在类加载的时候做一些数据初始化的操作

八、接口

1.接口概述

  • 接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。

  • Java中接口存在的两个意义

    1. 用来定义规范

    2. 用来做功能的拓展

2.接口特点

接口用关键字interface修饰

public interface 接口名 {}

类实现接口用implements表示

public class 类名 implements 接口名 {}

3.接口成员特点

  • 接口不能实例化

    我们可以创建接口的实现类对象使用

  • 接口的子类

    要么重写接口中的所有抽象方法

    要么子类也是抽象类

4.类和接口的关系

  • 类与类的关系

    继承关系,只能单继承,但是可以多层继承

  • 类与接口的关系

    实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

  • 接口与接口的关系

    继承关系,可以单继承,也可以多继承

5.接口组成更新

  • 常量:public static final

  • 抽象方法:public abstract

  • 默认方法(Java 8)

  • 格式:public default 返回值类型 方法名(参数列表) { }

  • 作用:解决接口升级的问题

  • 静态方法(Java 8)

  • 格式:public static 返回值类型 方法名(参数列表) { }

  • 私有方法(Java 9)

  • 私有方法产生原因

    Java 9中新增了带方法体的私有方法,这其实在Java 8中就埋下了伏笔:Java 8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性

  • 定义格式

    • 格式1:private 返回值类型 方法名(参数列表) { }

    • 格式2:private static 返回值类型 方法名(参数列表) { }

    九、多态       

        同一个对象,在不同时刻表现出来的不同形态

举例:猫

可以说猫是猫  猫 cat = new 猫();

也可以说猫是动物  动物 animal = new 猫();

猫在不同时刻展现出来不同形态,就是多态

1.多态的前提

  • 要有继承或实现关系

  • 要有方法的重写

  • 要有父类引用指向子类对象

2.成员访问特点

  • 成员变量

    编译看父类,运行看父类

  • 成员方法

    编译看父类,运行看子类

3.多态的好处和弊端

  • 好处

    提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作

  • 弊端

    不能使用子类的特有成员

4.多态中的转型

  • 向上转型

    父类引用指向子类对象就是向上转型

  • 向下转型

    格式:子类型 对象名 = (子类型)父类引用;

5.多态中转型存在的风险和解决方案

  • 风险

    如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException

  • 解决方案

    • 关键字

      instanceof

    • 使用格式

      变量名 instanceof 类型

      通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果

abstract class Animal {
    public abstract void eat();
}

class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }

    public void watchHome(){
        System.out.println("看家");
    }
}

class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

public class Test4Polymorpic {
    public static void main(String[] args) {
        useAnimal(new Dog());
        useAnimal(new Cat());
    }

    public static void useAnimal(Animal a){  // Animal a = new Dog();
                                             // Animal a = new Cat();
        a.eat();
        //a.watchHome();

//        Dog dog = (Dog) a;
//        dog.watchHome();  // ClassCastException  类型转换异常
      
        // 判断a变量记录的类型, 是否是Dog
        if(a instanceof Dog){
            Dog dog = (Dog) a;
            dog.watchHome();
        }
    }

}

十、内部类

1.基本使用

  • 内部类概念

    • 在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类

  • 内部类定义格式

/*
    格式:
    class 外部类名{
        修饰符 class 内部类名{
        
        }
    }
*/

class Outer {
    public class Inner {
        
    }
}

内部类的访问特点

  • 内部类可以直接访问外部类的成员,包括私有

  • 外部类要访问内部类的成员,必须创建对象

/*
    内部类访问特点:
        内部类可以直接访问外部类的成员,包括私有
        外部类要访问内部类的成员,必须创建对象
 */
public class Outer {
    private int num = 10;
    public class Inner {
        public void show() {
            System.out.println(num);
        }
    }
    public void method() {
        Inner i = new Inner();
        i.show();
    }
}

2.成员内部类

  • 成员内部类的定义位置

    • 在类中方法,跟成员变量是一个位置

  • 外界创建成员内部类格式

    • 格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

    • 举例:Outer.Inner oi = new Outer().new Inner();

  • 私有成员内部类

    • 将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。

class Outer {
    private int num = 10;
    private class Inner {
        public void show() {
            System.out.println(num);
        }
    }
    public void method() {
        Inner i = new Inner();
        i.show();
    }
}
public class InnerDemo {
    public static void main(String[] args) {
		//Outer.Inner oi = new Outer().new Inner();
		//oi.show();
        Outer o = new Outer();
        o.method();
    }
}

静态成员内部类

  • 静态成员内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

  • 静态成员内部类中的静态方法:外部类名.内部类名.方法名();

class Outer {
    static class Inner {
        public void show(){
            System.out.println("inner..show");
        }

        public static void method(){
            System.out.println("inner..method");
        }
    }
}

public class Test3Innerclass {
    /*
        静态成员内部类演示
     */
    public static void main(String[] args) {
        // 外部类名.内部类名 对象名 = new 外部类名.内部类名();
        Outer.Inner oi = new Outer.Inner();
        oi.show();

        Outer.Inner.method();
    }
}

3.局部内部类

  • 局部内部类定义位置

    • 局部内部类是在方法中定义的类

  • 局部内部类方式方式

    • 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用

    • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

class Outer {
    private int num = 10;
    public void method() {
        int num2 = 20;
        class Inner {
            public void show() {
                System.out.println(num);
                System.out.println(num2);
            }
        }
        Inner i = new Inner();
        i.show();
    }
}
public class OuterDemo {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method();
    }
}

4.匿名内部类

  • 匿名内部类的前提

    • 存在一个类或者接口,这里的类可以是具体类也可以是抽象类

  • 匿名内部类的格式

    • 格式:new 类名 ( ) { 重写方法 } new 接口名 ( ) { 重写方法 }

new Inter(){
    @Override
    public void method(){}
} 
  • 匿名内部类的本质

    • 本质:是一个继承了该类或者实现了该接口的子类匿名对象

  • 匿名内部类的细节

    • 匿名内部类可以通过多态的形式接受

Inter i = new Inter(){
  @Override
    public void method(){
        
    }
}

匿名内部类直接调用方法

interface Inter{
    void method();
}

class Test{
    public static void main(String[] args){
        new Inter(){
            @Override
            public void method(){
                System.out.println("我是匿名内部类");
            }
        }.method();	// 直接调用方法
    }
}

匿名内部类在开发中的使用

  • 当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码

/*
    游泳接口
 */
interface Swimming {
    void swim();
}

public class TestSwimming {
    public static void main(String[] args) {
        goSwimming(new Swimming() {
            @Override
            public void swim() {
                System.out.println("铁汁, 我们去游泳吧");
            }
        });
    }

    /**
     * 使用接口的方法
     */
    public static void goSwimming(Swimming swimming){
        /*
            Swimming swim = new Swimming() {
                @Override
                public void swim() {
                    System.out.println("铁汁, 我们去游泳吧");
                }
            }
         */
        swimming.swim();
    }
}

十一、Lambda表达式

1.函数式编程思想概述

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”

面向对象思想强调“必须通过对象的形式来做事情”

函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”

而我们要学习的Lambda表达式就是函数式思想的体现

2.Lambda表达式的标准格式

  • 格式:

    (形式参数) -> {代码块}

    • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可

    • ->:由英文中画线和大于符号组成,固定写法。代表指向动作

    • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

  • 组成Lambda表达式的三要素:

    • 形式参数,箭头,代码块

3.Lambda表达式的使用前提

  • 使用Lambda必须要有接口

  • 并且要求接口中有且仅有一个抽象方法

4.Lambda表达式和匿名内部类的区别

  • 所需类型不同

    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类

    • Lambda表达式:只能是接口

  • 使用限制不同

    • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类

    • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式

  • 实现原理不同

    • 匿名内部类:编译之后,产生一个单独的.class字节码文件

    • Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

5.练习

  • Lambda表达式的使用前提

    • 有一个接口

    • 接口中有且仅有一个抽象方法

  • 练习描述

    无参无返回值抽象方法的练习

  • 定义一个接口(Eatable),里面定义一个抽象方法:void eat();

  • 定义一个测试类(EatableDemo),在测试类中提供两个方法

    • 一个方法是:useEatable(Eatable e)

    • 一个方法是主方法,在主方法中调用useEatable方法

//接口
public interface Eatable {
    void eat();
}
//实现类
public class EatableImpl implements Eatable {
    @Override
    public void eat() {
        System.out.println("一天一苹果,医生远离我");
    }
}
//测试类
public class EatableDemo {
    public static void main(String[] args) {
        //在主方法中调用useEatable方法
        Eatable e = new EatableImpl();
        useEatable(e);

        //匿名内部类
        useEatable(new Eatable() {
            @Override
            public void eat() {
                System.out.println("一天一苹果,医生远离我");
            }
        });

        //Lambda表达式
        useEatable(() -> {
            System.out.println("一天一苹果,医生远离我");
        });
    }

    private static void useEatable(Eatable e) {
        e.eat();
    }
}
  • 练习描述

    有参无返回值抽象方法的练习

  • 操作步骤

    • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);

    • 定义一个测试类(FlyableDemo),在测试类中提供两个方法

      • 一个方法是:useFlyable(Flyable f)

      • 一个方法是主方法,在主方法中调用useFlyable方法

public interface Flyable {
    void fly(String s);
}

public class FlyableDemo {
    public static void main(String[] args) {
        //在主方法中调用useFlyable方法
        //匿名内部类
        useFlyable(new Flyable() {
            @Override
            public void fly(String s) {
                System.out.println(s);
                System.out.println("飞机自驾游");
            }
        });
        System.out.println("--------");

        //Lambda
        useFlyable((String s) -> {
            System.out.println(s);
            System.out.println("飞机自驾游");
        });

    }

    private static void useFlyable(Flyable f) {
        f.fly("风和日丽,晴空万里");
    }
}
  • 练习描述

    有参有返回值抽象方法的练习

  • 操作步骤

    • 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);

    • 定义一个测试类(AddableDemo),在测试类中提供两个方法

      • 一个方法是:useAddable(Addable a)

      • 一个方法是主方法,在主方法中调用useAddable方法

public interface Addable {
    int add(int x,int y);
}

public class AddableDemo {
    public static void main(String[] args) {
        //在主方法中调用useAddable方法
        useAddable((int x,int y) -> {
            return x + y;
        });

    }

    private static void useAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println(sum);
    }
}

6.Lambda表达式的省略模式

省略的规则

  • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个

  • 如果参数有且仅有一个,那么小括号可以省略

  • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字

public interface Addable {
    int add(int x, int y);
}

public interface Flyable {
    void fly(String s);
}

public class LambdaDemo {
    public static void main(String[] args) {
//        useAddable((int x,int y) -> {
//            return x + y;
//        });
        //参数的类型可以省略
        useAddable((x, y) -> {
            return x + y;
        });

//        useFlyable((String s) -> {
//            System.out.println(s);
//        });
        //如果参数有且仅有一个,那么小括号可以省略
//        useFlyable(s -> {
//            System.out.println(s);
//        });

        //如果代码块的语句只有一条,可以省略大括号和分号
        useFlyable(s -> System.out.println(s));

        //如果代码块的语句只有一条,可以省略大括号和分号,如果有return,return也要省略掉
        useAddable((x, y) -> x + y);
    }

    private static void useFlyable(Flyable f) {
        f.fly("风和日丽,晴空万里");
    }

    private static void useAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println(sum);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值