面向对象(OOP)基础+进阶

面向对象(OOP)基础+进阶

1.类:

类是对现实生活中一类具有共同属性和行为的事物的抽象

【类】是对事物,也就是对象的一种描述,可以将类理解为一张设计圈,

根据设计圈,可以创建出具体存在的事物

类的组成:

1.属性

该事物的各种特征

例如我的属性:姓名,年龄,毕业学校

2.行为

该事物存在的时期(能做的事情)

例如我的行为:学习Java,吃饭,睡觉

类是对象的描述,对象是类的实体

类的定义

类的组成:属性和行为

属性:在代码中通过成员变量来体现(类中方法外的变量)

行为:在代码中通过成员方法来体现(和前面的方法相比去掉static关键词即可)

类的定义步骤:

1.定义类

2.编写类的成员变量

3.编写类的成员方法

案例:

public class 类名{
  //成员变量
	变量1的数据类型 变量1;
	变量2的数据类型 变量2;
	
		…………

  //成员方法
	 方法1;
	 方法2;
		…………
}
2.创建对象

格式:类名 对象名 = new 类名();

例: Student s = new Student();

​		 Dog d = new Dog();

​		 Cat c = new Cat();

使用对象

1.调用成员变量

格式:对象名.变量名

例: s.name;

调用成员方法(动态方法)

格式:对象名 . 方法名();

例: s . study();

成员变量:类中方法外的变量(在整个方法内都可以被访问到,可以应用于需要多次创建的情况下,在成员变量位置调用,可以节省内存)

//此时,String name;和int j;就是两个成员变量

//局部变量:方法中的变量
//此时,int i = 0;和int j = 0;是两个局部变量
public class Student{

	String name;//成员变量
public  void study(){
	int i = 0;//局部变量
	System.out.println("好好学习")}
public void doHomework(){
	System.out.println("多做练习")int j = 0//局部变量
}
    int age;//成员变量
}
3.Java中的垃圾回收机制:

注意:当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会将判定为内存中的”垃圾“

垃圾会被Java垃圾回收器,空闲的时候自动进行清理。

4.面向对象—封装

**封装的特点是:**隐藏是实现细节,仅对外暴露公共的访问方式

封装常见的体现

(1)私有成员变量,提供setXxx和getXxxv方法
(后面boot项目中可以使用Lombok工具类中的注解简化开发)

(2)将代码抽取到方法中,这是对代码的一种封装

(3)将属性抽取到类当中,这是对数据的一种封装

**封装的好处:**提高了代码的安全性,复用性

private关键字:

  1. 是一个权限修饰符
  2. 可以修饰成员(成员方法和成员变量)
  3. 被private修饰的成员只能在本类中才能被访问

要想访问被 private 修饰的变量,只能通过set,get方法去在测试类文件中获取

因此,需要在模板中加入设置方法(setAge赋值通道)和获取方法(getAge),获取通道),然后在方法里面加入判断,最后在测试代码中使用获取方法中的数据来获得被private修饰的变量

针对private修饰的成员变量,如果需要被其他类使用,在JavaBean类提供相应的操作:

1.提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰

2.提供“set变量名()”方法,用于设置成员变量的值,方法用public修饰

private的使用

一个标准的类的编写:

1.把成员变量用private修饰

2.提供对应的setXxx();和getXxx();方法

3.在测试文件中调用成员方法使用

注意事项:后面会学到反射,暴力反射可以获取到被private修饰的内容

5.this关键字

局部变量和成员变量如果重名,Java使用的是就近原则

在变量名前加入 this. 则可以表示成员变量

具体格式: this.变量名

注意:如果想把一个变量标识为成员变量,就在它前面加一个this.

然后可以在测试类中使用

6.构造方法

构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,以及实例变量的初始化,换句话说:构造方法是用来创建对象,并且同时给对象的属性赋值

比如:JavaBean类中的无参构造和带参构造

格式:

1.方法名于类名相同,大小写也要保持一致

2.没有返回值类型,连void都没有

3.不能手动调用构造方法

public class Student{
    //无参构造
    public Student(){
        
    }
    //有参构造
    public Student(String name){
        this.name = name;
    }
}

执行时机:

1.创建对象的时候调用,每创建一次对象,就会执行一次构造方法

2.不能手动调用构造方法(仅仅需要在测试类中创建一个对象并使用就行)

**构造方法的作用:**用于给对象的数据(属性)进行初始化

构造方法的注意事项:

1.构造方法的创建:

如果没有定义构造方法,系统将给出一个,默认的无参数构造方法

如果定义了构造方法,系统将不在提供默认的构造方法

2.构造方法的重载:

如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法

3.推荐的使用方式:

无论是否使用,都手动书写无参数构造方法,和带参数构造方法

无参构造方法和带参构造方法的区别是:

无参构造方法中,在测试文件中,必须先创建对象,然后调用成员方法在里面赋值

带参构造方法中,可以直接在创建对象的时候传入参数,

注意:无论是无参还是带参构造方法,都必须在JavaBean类处提供setXxx\getXxx方法

  • set方法是设置,要传入具体参数,

  • get方法中是获取,则不需要

声明:可以偷懒使用快捷键输入setXxx\getXxx方法

操作方式:鼠标右键找到Generate,点击进去,第一个Constructor是提供带参构造方法

下面的set是提供setXxx方法,get是提供getXxx方法

还有一个set and get是一键提供setXxx和getXxx方法,但是要进入界面之前按下ctrl+a,是实现全选

6.分包思想

包的概念:

包:本质上就是文件夹

创建包:(单级包,多级包)

多级包之间使用“.”进行分割

多级包的定义规范:公司的网站地址翻转(去掉www)

比如:黑马程序员的网站址为www.itheima.com

后面我们所定义的包的结构就是:com.itheima.其他的包名

包的命名规则:字母都是小写

包的注意事项:

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

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

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

类与类之间的访问:

同一个包下的访问

​ 不需要导包,直接使用即可(意思是同一个包下的类文件是互通的)
不同包下的访问

​ 1.import导包后访问

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

例如:com.itheima.test2.Student stu = new com.itheima.test2.Student ( );

应用场景:多个包下,出现了相同的类名称,就可以使用这种访问进行区分

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

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

import需要写在package下面

class需要在import下面

7.static关键字

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

被static修饰的成员变量,一般叫做静态变量

被static修饰的成员方法,一般叫做静态方法

static 修饰的特点:

1.被该类的所有对象【共享】(意思就是:该类的所有对象都可以使用)

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

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

(类加载的时候,被static修饰的变量也同时加载)

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

3.可以通过类名使用(调用格式为: 类名.方法名

static 关键字的注意事项:

1.静态方法只能访问静态的成员

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

3.静态方法中是没有this关键字的

总结:静态方法中,只能访问静态成员,静态中没有this关键字

7.面向对象—继承

继承概述:

继承:让类与类之间产生关系(子父类关系),子类可以直接使用父类中非私有的成员

​ (父类里面有非私有的成员,子类直接使用父类里面的非私有成员,就类似于父类有资产,子类直接调用)

继承的格式:

格式:public class 子类名 extends 父类名{ }

范例:public class Zi extends Fu { }

Fu :是父类,也被称为基类,超类

Zi :是子类,也被称为派生类

继承的好处和弊端:

继承的好处:

1.提高了代码的复用性

2.提高了代码的维护性

3.让类与类之间产生了关系,是多态的前提

继承主要解决的问题是:共性的抽取,实现代码的复用

继承的弊端:

1.继承是侵入性的

2.降低了代码的灵活性

继承关系,导致了必须拥有父类非私有属性和方法,让子类自由的世界中多了些约束

3.增强了代码的耦合性

代码与代码之间存在关联都可以将其称之为“耦合”。(比如:在父类中删除了一个成员变量之后,在子类中的调用该成员变量的都会报错,就类似于父类的资产没了之后,子类也会受到影响)

继承的特点:

Java只支持单继承(一个儿子只能拥有一个父亲),不支持多继承(一个儿子不能拥有多个父亲),但支持多层继承(儿子可以继承父亲,父亲可以继承爷爷)。

子父类当中,如果出现了重名的成员变量,系统会默认打印 子类 中局部变量(就近原则)

需求:1.在控制台打印本类成员变量: System.out.println (this.a);

需求:2.在控制台打印父类成员变量: System.out.println (super.a);

注意:如果子父类中出现了重名的成员变量,如果非要打印父类中的成员变量,那么就在输出语句中使用 super . 变量名

如果非要打印子类中的成员变量,那么就在输出语句中使用 this . 变量名

当我们在方法中使用一个变量的时候,它会先找自己的局部变量,如果局部变量不存在,就会去找自己的成员变量,成员变量不存在的话就会去找父类当中的成员变量

继承的成员变量访问特点:

在子类方法中访问一个变量:

1.先在子类的局部范围中找

2.如果子类的局部范围中不存在,就在子类的成员范围中找

3.如果子类的成员范围中不存在,就在父类的成员范围中找

注意:如果子父类中,出现了重名的成员变量,通过就近原则,会优先使用子类的

如果一定要使用父类的,可以通过super关键字,进行区分

super关键字的用法和this关键字的用法相似:

this:代表本类对象的引用

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

java 中若要在子类调用父类的方法,需使用关键字super。


关键字访问成员变量访问成员方法访问构造方法
thisthis . 成员变量 访问本类成员变量this.成员方法 (…) 访问本类成员方法this(…)访问本类构造方法
supersuper . 成员变量 访问父类成员变量super . 成员方法(…) 访问父类成员方法super(…) 访问父类构造方法

继承中成员方法的访问特点:

通过子类对象访问一个方法:

1.先在子类成员范围找

2.如果子类成员范围中没有,就到父类成员范围找

3.如果父类成员范围中也不存在,程序就会报错

方法重写的应用场景:

当子类需要父类的功能,而功能主体子类有自己的特有内容

可以重写父类中的方法,这样,即沿袭了父亲的功能,有定义了子类特有的内容

注意:

方法重写:在继承体系中,子类出现了和父类一模一样的方法声明(方法名,参数列表,返回值类型)

方法重载:在同一个类中,方法名相同,参数列表不同,与返回值无关

下面图片是方法重写的案例:(手机1:有打电话和英语语音助手的功能,更新手机1后的手机为手机2,手机2里面语音助手加入了说中文的能力,因此用方法重写在原本父类【手机1】的基础上在子类【手机2】中加入了新功能,然后在测试类文件中创建对象,然后调用成员方法实现)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q2LtblOe-1678926022953)(面向对象.assets/image-20221127223156618.png)]

方法重写注意事项:

1.父类中私有方法(private)不能被重写

2.父类静态方法(static),子类必须通过静态方法(static)进行重写,父类非静态方法,子类也必须通过非静态方法进行重写

注意:静态方法不能被重写!!!如果子类中,也存在一个方法声明一模一样的方法

可以理解为,子类将父类中同名的方法,隐藏了起来,并非是方法重写!

3.子类重写父类方法时,访问权限必须大于等于父类

权限修饰符(权限级别由大到小排列)

修饰符同一个类中同一个包中子类无关类 (意思是同一个包中可以随便访问)不同包的子类不同包的无关类
public
protected
默认
private

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

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

为什么呢?

子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据

子类初始化之前,一定要先完成父类初始化

怎么初始化?

每个子类构造方法的第一条语句默认都是: super ( ) ;

注意:如果我们编写的类,没有手动指定父类,系统也会自动继承Object(Java继承体系中最顶层父类)

如果父类中没有空参构造方法,只有带参构造方法,会出现什么现象呢?

1.子类通过super();手动调用父类的带参的构造方法

2.子类通过this去调用本类的其他构造方法,本类其他的构造方法再通过super去手动调用父类的带参的构造方法。(不推荐使用)

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

抽象类概述:

抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以被定义为抽象方法

抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类(抽象方法必须存在于抽象类当中)

案例:定义猫类(Cat)和狗类(Dog)

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

狗类成员方法:eat(狗吃骨头),drink(喝水…)

那么这个eat的成员方法被定义为了抽象方法,因为父类中无法给出猫和狗的具体eat,而drink的成员方法就可以在父类中进行统一写出

抽象类的定义格式:

public abstract class类名{ }

抽象方法的定义格式:

public abstract 返回值类型 方法名(参数列表);

在其他类中写抽象方法内的具体内容时,需要用方法名+回车键,快捷生成,然后再在写东西 ,具体案例如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvXLUWxq-1678926022954)(面向对象.assets/image-20221127223627785.png)]

抽象类注意事项:

1.抽象类不能实例化(不能创建对象)

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

3.抽象类中可以存在构造方法

4.抽象类的子类

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

要么是抽象类(用的很少,知道就行)

模板设计模式:

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

小结:抽象模式设计的优势,模板已经定义了通用结构,使用者只需要关系自己需要实现的功能即可

final关键字:

final关键字是最终的意思,可以修饰(方法,变量,类)

final修饰的特点:

1.修饰方法:表明该方法是最终方法,不能被重写

2.修饰变量:表明该变量是常量,不能再次被赋值

3.修饰类:表示该类是最终类,不能被继承

当变量是基本数据类型的时候,final修饰指的是基本类型的数据值不能发生改变

当变量是引用数据类型的时候,final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的

代码块概述与分类

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

分类:

  • 局部代码块

位置:方法中定义

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

  • 构造代码块:

位置:类中方法外定义

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

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

  • 静态代码块:

位置:类中方法外定义

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

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

1、父类静态代码块优先于子类静态代码块执行,静态代码块相较于其他是最早执行。(因为static修饰的东西在代码加载时就执行了)

2、父类实例代码块和父类构造方法紧接着执行。

3、子类的实例代码块和子类构造方法紧接着再执行。

4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行(静态代码块只执行一次)。

接口介绍:

当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口

接口也是一种引用数据类型,它比抽象类还要抽象

接口存在的两个重要意义:

1.规则的定义

2.程序的扩展性

接口的定义和特点:

1.接口用关键字 interface 来定义

public interface 接口名 { }

2.接口不能实例化(不能创建对象,然后调用)

3.接口和类之间是实现关系,通过implements关键字表示

public class 类名 implements 接口名 { }

4.接口的子类(实现类)

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

要么是抽象类

使用一个接口里面的方法的具体步骤:

1.创建实现类,通过implements关键字去实现接口

2.重写方法

3.创建实现类对象

4.调用重写后的方法

注意:接口和类的实现关系,可以单实现,也可也多实现

public class 类名 implements 接口名1,接口名2 { }

和继承进行区别一下,继承只能单继承,不能多继承,但是可以多层继承

接口中成员的特点:

成员变量:

只能是常量(注意:在定义常量名称的时候要遵守常量的命名规则,常量字母全部大写)

默认修饰符:public static final

//系统中会默认在成员变量前加入,如果我们不写,也不会报错

构造方法:没有

成员方法:

只能是抽象方法

默认修饰符:public abstract

//系统中会默认在成员方法前加入,如果我们不写,也不会报错

JDK8版本中接口成员的特点:

1.JDK版本后

(1).允许在接口中定义非抽象方法,但是需要使用关键字default修饰,这些方法就是默认方法

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

2.接口中默认方法的定义格式:

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

范例:public default void show ( ) { }

3.接口中默认方法的注意事项:

默认方法不是抽象方法。所以把不强制被重写,但是可以被重写,重写的时候去掉default关键字

public可以省略,default不能省略

如果实现了多个接口,多个接口中存在相同的方法声明,那么系统就不承认接口中的相同方法声明,因此需要在实现类中重写该方法

接口中允许定义static静态方法

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

范例:public static void show ( ) { }

接口中静态方法的注意事项:

静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

只能通过 接口名 . 方法名

public 可以省略,但是static不能省略

JDK9版本中接口成员的特点:

接口中私有方法的定义格式:

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

范例1:private void show ( ) { }

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

范例2:private static void method(){ }

接口的使用思路:

1.如果发现一个类中所有的方法都是抽象方法,那么就可以将该类,改进为一个接口

2.涉及到了接口大面积更新方法,而不想去修改每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法public default void 方法名( ){ }

3.希望默认方法调用的更加简洁,可以考虑设计为static静态方法(需要去掉default关键字)

4.默认方法中出现了重复的代码,可以考虑抽取出一个私有方法。(需要去掉default关键字)

类和接口的关系:

1.类和类的关系:

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

2.类和接口的关系:

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

3.接口与接口的关系:

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

8.面向对象—多态

多态概念:

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

父类的引用指向子类对象

举例:猫

我们可以说猫是猫:猫 cat = new 猫();

我们也可以猫是动物:动物 animal = new 猫();

这里猫在不同的时刻表现出来了不同的形态,这就是多态

多态的前提和体现:

1.有继承/实现关系

2.有方法重写

3.有父类引用指向子类对象

多态中成员访问特点:

首先我们要知道:Java中一个程序的实现需要两个步骤,需要先进行源代码编译,查看代码中是否有错误,如果没有错误,代码才会运行

构造方法:同继承一样,子类会通过super访问父类构造方法

成员变量:编译看左边(父类),执行看左边(父类)

(意思是成员变量在编译期间检查父类中有没有这个成员变量,如果没有就报错,如果存在就执行左边的父类,因为在接口或者是抽象类当中,变量会被public static final修饰,因此变量的值无法改变,也可也称之为常量)

成员方法:编译看左边(父类),执行看右边(子类)

(意思是成员方法在编译的过程中,首先会检查父类中是否存在这个成员方法,如果没有就报错,如果存在的就执行右边的子类,因为在多态的情况下,父类中的成员方法会被子类重写覆盖,因此执行输出的是子类重写后的结果)

为什么成员变量和成员方法的访问不一样呢?

因为成员方法中存在重写,而成员变量在接口/抽象类中被定义出来的时候会默认加上public static final关键字来修饰,因此这时候成员变量就变成了常量,无法被修改,因此只能执行父类中原有的数据

多态的好处和弊端:

多态的好处:提高了程序的扩展性

具体体现:定义方法的时候,使用父类型作为参数,传入调用父类的方法中,使方法就可以接收这父类的任意子类对象

多态的弊端:

不能直接使用子类的特有功能

多态中的转型:

1.向上转型

从子到父 例如:Fu f = new Zi ( );

父类引用指向子类对象

2.向下转型(强制转换)

从父到子 (向下转型中隐含着强制转换) 例如:Zi z = (Zi) f ;

父类引用转为子类对象

避免强转出现的问题:

关键字:instanceof

使用格式:

变量名 instanceof 类型

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

但是在通常使用instanceof的时候,会和if语句判断一起使用

if(a instanceof Dog){

Dog d = (Dog)a;

dog.watchHome ( ) ;

}

9.内部类

内部类概述:

内部类:就是在一个类中定义一个类,举例在A类的内部定义一个B类,那么A类就被称为外部类,B类就被称为内部类

范例:  public class Outer {

public class Inner {

  }

}

内部类的访问特点:

1.内部类可以直接访问外部类的成员,包括私有(private)

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

成员内部类:

按照内部类在类中的定义的位置不同,可以分为如下两种格式:

1.在类的成员位置:成员内部类

2.在类的局部位置:局部内部类

成员内部类,外界该如何创建对象使用呢?

格式:外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();

范例:Outer.Inner oi = new Outer().new Inner ( ) ;

成员内部类

成员内部类,也属于(成员),既然是成员就可以被一些修饰符所修饰

private:

私有成员内部类访问:在自己所在的外部类中创建一个方法,方法里面创建内部类的对象,然后调用,最后在主方法中创建外部类对象,并调用外部类对象中的方法即可实现

static:

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

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

局部内部类:

局部内部类是在方法中定义的类,所以外界是无法直接使用的,需要在方法内部创建对象并使用

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

匿名内部类:
概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部【主方法】)

前提:需要存在一个接口或类

 

格式:

new 类名或者接口名(){

重写方法;

} ;

理解:匿名内部类是将(继承\实现)(方法重写)(创建对象)这三个步骤,放在了一步进行

范例:new Inter(){

public void show (){

}

};

10.Lambda表达式

Lambda表达式的标准格式:

1.格式:(形式参数)-> {代码块} ;

2.形式参数:如果有多个参数,参数之间用逗号隔开,

如果没有参数,直接()就行,不用写东西

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

4.代码块:是我们具体要做的事情,也就以前我们写的方法体内容(比如:输出语句System.out.println ( ); )

Lambda表达式的使用前提:

1.有一个接口

2.接口中有且只有一个抽象方法

注意:如果Lambda所操作的接口中的方法,有返回值,一定要通过return语句,将结果返回,否则会出现编译错误

Lambda表达式的省略模式(偷懒模式,知道就行,但是不推荐使用):

省略规则:

1.当只有一个参数的时候,参数类型可以省略,但是又多个参数的情况下,不能只省略一个

2.如果参数有且只有一个,那么小括号可以省略

3.如果代码块的语句只有一个,可以省略大括号和分号,甚至是return

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

所属类型不同:

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

2.Lambda表达式:只能是接口

使用限制不同:

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

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

实现原理不同:

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

部【主方法】)

前提:需要存在一个接口或类

格式:

new 类名或者接口名(){

重写方法;

} ;

理解:匿名内部类是将(继承\实现)(方法重写)(创建对象)这三个步骤,放在了一步进行

范例:new Inter(){

public void show (){

}

};

10.Lambda表达式

Lambda表达式的标准格式:

1.格式:(形式参数)-> {代码块} ;

2.形式参数:如果有多个参数,参数之间用逗号隔开,

如果没有参数,直接()就行,不用写东西

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

4.代码块:是我们具体要做的事情,也就以前我们写的方法体内容(比如:输出语句System.out.println ( ); )

Lambda表达式的使用前提:

1.有一个接口

2.接口中有且只有一个抽象方法

注意:如果Lambda所操作的接口中的方法,有返回值,一定要通过return语句,将结果返回,否则会出现编译错误

Lambda表达式的省略模式(偷懒模式,知道就行,但是不推荐使用):

省略规则:

1.当只有一个参数的时候,参数类型可以省略,但是又多个参数的情况下,不能只省略一个

2.如果参数有且只有一个,那么小括号可以省略

3.如果代码块的语句只有一个,可以省略大括号和分号,甚至是return

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

所属类型不同:

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

2.Lambda表达式:只能是接口

使用限制不同:

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

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

实现原理不同:

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

2.Lambda表达式:编译之后,没有一个单独的 .class 字节码文件,对应的字节码文件会在运行的时候动态生成(并且不会保留在硬盘中)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值