Java语法基础(抽象,接口,内部类,lambda表达式的概念和用法)
多态:链接: 点击看这个基础方便理解抽象类.
修饰符:abstract,final,static
目录
抽象类
关键字:父类 abstract 子类 employ
概念:用abstract修饰的类都是抽象类
可以把抽象类当作一个正常的类:
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
抽象类一般什么时候用:当2个或多个类中有重复部分的时候,我们可以抽象出来一个基类,如果希望这个基类不能被实例化,就可以把这个基类设计成抽象类,也就是简化项目,提高复用性。
接口(特殊的抽象类)
当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
概念:
- 是接口使用者与接口实现者共同遵守的一个标准、约定
- 是一种功能,每实现一个接口都相当于为类扩充了一种功能
-
从语法角度上来说,接口就是一个特殊的抽象类
关键字:父类:interface 子类:implements
特点:
- 接口中的属性都是公开静态常量:public static final 数据类型 属性名;
- 接口中也可以创建对象的引用
- 接口中的方法都是公开抽象方法:public abstract 返回值类型 方法名(形参列表);
- 接口中没有构造方法!不参与对象的创建过程,不能创建对象,可以声明引用!编译后依然生成.class文件
- 注意:若实现类不想成为抽象类,就必须实现接口中的所有方法
接口中变量和方法的形式
写法一 public static final int A = 10; public static final double B = 2.5; public abstract void m1(); public abstract void m2(); 写法二 int A = 10; double B = 2.5; void m1(); void m2(); 这两者是相同的,在编译的时候,编译器会把写
写法二自动补全为写法一的形式
接口的继承:
- 类与类之间是单继承 class 子类名 extends 父类名{}
- 接口与接口之间是多继承 interface 子接口 extends 父接口1,父接口2{}
类与接口的关系:
-
多实现: class 类名 implements 接口1,接口2{}
-
先继承,再实现:class 子类名 extends 父类名 implements 接口1,接口2{}
注意:继承与实现的顺序不可变
接口的多态
链接: 与抽象类的多态一样.
接口的类型转换
链接: 与抽象类的类型转换一样.
接口的回调
概念:先有接口的使用者,后有接口的实现者
Student[] s = { new Student("小明",18,88), new Student("小吴",19,68), new Student("小红",16,100), new Student("康康",20,99), new Student("翠花",17,0) }; Array.sort(s)
任何想要通过sort排序的类型,都需要实现Comparable接口,重写接口中的compareTo();
我的理解
首先分为3个部分还有一个真正的实现部分方法
1 sort()是一个打开实现类方法的开关 与接口实现类没有继承和实现关系只不过负责打开
2 Student是实现类
3 Comparable 接口 里面有方法compareTo
注意sort之所以能对int进行排序 是因为interger继承了Comparable
步骤
sort是工具类 我们直接导入工具类,然后在实现类中继承接口并实现方法
难理解点:student需要执行操作的元素吗,为什么student是实现类。
答:自己元素需要有这些方法才能调用
JDK高本对接口新增的特性
-
JDK8.0
静态方法
public static 返回值类型 方法名(形参列表){
//方法实现
}
默认方法
public default 返回值类型 方法名(形参列表){
//方法实现
}
注意:访问修饰符依然是public
-
JDK9.0
私有方法
private 返回值类型 方法名(形参列表){
//方法实现
}
抽象类和接口的区别
接口的分类
- 常量接口 只有常量,没有方法;把一些经常使用但不会改变的数据定义到常量接口中
- 标记接口 即无属性,也无方法,只是作为一个标记!Serializable,对象序列化、
- 函数接口 接口中只有一个抽象方法(静态方法、默认方法、私有方法无要求)
- 普通接口 接口中至少有两个抽象方法
内部类
概念:在类的内部在定义一个类,也可以在类内部的方法内定义一个类
特点:
- 内部类同样是一个独立的类,编译生成独立的.class文件
- 内部类可以作为外部类的必要组成部件
分为4种
- 成员内部类
- 静态内部类(在成员内部类前加上修饰词static)
- 局部内部类
- 匿名内部类 (局部内部类的特殊形式)
成员内部类概念:
概念:定义在类的内部,方法的外部的类,即成员内部类,与属性、方法同级
语法:外部类类名.内部类类名 内部类对象名 = 外部类对象名.new 内部类类名()
特点:
1.编译后会生成什么
编译后生成一个 名为 外部类类名$内部类类名.class 的字节码文件 用来区分内部类与外部类
2.内部类中可以声明什么
只可以声明非静态成员,不能声明静态成员
3.内部类中可以使用什么
a.可以使用外部类所有的成员和静态成员 私有的也可以用
b.也可以使用本类中声明的成员
c.注意 外部类属性 内部类属性 局部变量是可以命名冲突的,但局部变量优先
内部类属性---this.内部类属性名
外部类属性---外部类类名.this.外部类属性名
4.如何创建内部类对象
a.先创建外部类对象
Outer outer = new Outer();
b.再通过特殊语法创建内部类对象
外部类类名.内部类类名 对象名 = 外部类对象.new 内部类类名();
Outer.Inner inner = outer.new Inner();
class Day14{ public static void main(String[] args){ Outer out = new Outer(); Outer.Inner inn = out.new Inner(); inn.inner_method(); } } class Outer{ private String str = "外部类私有属性"; class Inner{ String str = "内部类属性"; //注意:成员内部类中不允许定义静态成员 //static String staticStr = "内部类静态属性"; //public static void innerStatic_method(){} public void inner_method(){ String str = "内部类局部变量"; System.out.println(str);//内部类局部变量 System.out.println(this.str);//内部类属性 System.out.println(Outer.this.str);//外部类私有属性 //System.out.println(staticStr);//内部类静态属性 } } }
问题:成员内部类为什么不能有静态成员
答:成员内部类它与属性是同级的,类前没有static修饰的话,这个类都不会在类加载的时候进行,就不会分配内存,static也就没办法初始化
静态内部类
概念:被static修饰的成员内部类
1.编译后会生成什么
编译后生成一个 名为 外部类类名$内部类类名.class 的字节码文件 用来区分内部类与外部类
2.内部类中可以声明什么
可以声明静态成员 与 非静态成员
后续有用 记住!!!!!!!!!!!!! 内部类中可以有静态初始化代码块 且外部类的类加载并不会触发内部类类加载
3.内部类中可以使用什么
a.可以使用外部类的静态成员 不能使用非静态成员
b.可以使用本类自己的所有成员 和 静态成员
c.注意 外部类静态属性 内部类属性 局部变量是可以命名冲突的,但局部变量优先
内部类属性---this.内部类属性名
外部类静态属性---外部类类名.静态属性名
d.可以通过外部类类名.内部类类名.静态成员的形式 来使用内部类的静态成员
4.如何创建内部类对象
外部类类名.内部类类名 对象名 = new 外部类类名.内部类类名();
局部内部类
概念:声明在方法中的类,被称为局部内部类。 相当于一个局部变量
1.编译后会生成什么
编译后生成一个 名为 外部类类名$ 数字 内部类类名.class 的字节码文件 用来区分内部类与外部类
数字是来区分不同方法中 名字相同的内部类的
2.内部类中可以声明什么
不可以声明静态成员,可以声明非静态成员
3.内部类中可以使用什么
a.可以使用外部类所有的成员和静态成员 私有的也可以用
b.也可以使用本类中声明的成员
c.注意 外部类属性 内部类属性 局部变量是可以命名冲突的,但局部变量优先
内部类属性---this.内部类属性名
外部类属性---外部类类名.this.外部类属性名
d.局部内部类可以使用所在方法的局部变量 当局部内部类使用所在方法的局部变量时 该局部变量需要被final修饰 JDK1.8会自行添加final
4.如何创建内部类对象
局部内部类创建对象 和 正常创建对象的语法是相似的,只不过局部内部类创建对象的范围有要求
a.局部内部类只能在所声明的方法中被使用
b.从定义行开始 到定义它的方法结束
c.创建局部内部类的语法 和 创建普通类的语法一致
类名 对象名 = new 类名();
匿名内部类
概念:局部内部类的特殊形式
如果一个局部内部类符合以下两种条件,我们可以把它变成一个匿名内部类
-
该局部内部类有父项 — 是某个类子类或是某个接口的实现类
-
该类的对象 在该类的作用范围内 只被创建过一次
语法:
类名|接口名 引用 = new 类名|接口名(){ //方法实现 };
父项类型 对象名 = new 父项名(){
//类中的内容
}
特点:
- 局部内部类具有的所有特点,它都具有
- 匿名内部类必须是继承一个类或实现一个接口!!
- 匿名内部类只能创建一个对象
- 匿名内部类不能定义构造方法,只有一个默认的公开无参构造方法
优点:保证了编程思路的连贯性
缺点:可读性差
lambda表达式
概念:实现函数接口,并创建对象,更简洁的匿名内部类
他出现的作用:很好地解决了函数必须写在类里, 想要使用函数,必须创建包含其对应的对象这样的问题。让代码 更简洁,更好的传达程序员的意图。
语法:接口名 引用 = (形参列表) -> {//代码实现};
注意:lambda只能用来实现函数接口
表达式细节:
- 若Lambda表达式的执行部分,只有一行代码,{};可以省略
IB ib = (int a) ->
System.out.println("a="+a);
- Lambda表达式的参数类型可以省略,编译器可以自己推理!
IC ic = (a,b)-> System.out.println(a+b);
- Lambda表达式若只有一个参数,则数据类型和()都可省略
IB ib = a-> System.out.println("a="+a);
- 若Lambda表达式的执行部分,里面只有一个return语句,则{},return 都可以省略
IE ie = (a,b) -> a+b;
IE ie = (a,b) -> return a+b;//错误的写法,return语句不算一行代码
lambda表达式的作用:
将一个函数直接作为参数或对象,在语法上弥补了Java中不能函数作为参数的缺陷,极大程度的简化了语法,提高了开发效率
但是Lambda也会在一定程度上,降低代码的可读性,代码的可维护性不高
更多lambda表达式的用法下次更新
本文地址:https://blog.csdn.net/qq_42901537/article/details/108005541