1.final关键字
final修饰类
表示这个类不能被继承,没有子类。提高安全性,提高程序的可读性。
final修饰方法
表示这个方法不能被子类重写
final修饰变量
final 修饰某个变量(成员变量或局部变量),一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。
2.抽象类或抽象方法(abstract关键字)
有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。
我们把没有方法体的方法称为抽象方法。Java 语法规定,包含抽象方法的类必须是抽象类。
抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
• 不能用 abstract 修饰变量、代码块、构造器;
• 不能用 abstract 修饰私有方法、静态方法、final 的方法、final 的类
模板方法设计模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
3.接口
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的 is-a 关系,而接口实现则是 "能不能"的has-a 关系。
interface
可以声明属性
只能声明:public static final
接口使用:
接口不能创建对象,但可以被类实现
cla
如果接口的实现类是非抽象类,那么必须 重写接口中所有抽象方法 。
• 默认方法可以选择保留,也可以重写。
• 重写时,default 单词就不要再写了,它只用于在接口中表示默认方法,到类中就没有默认方法的概念了
• 接口中的静态方法不能被继承也不能被重写
public interface usb {
public void start();
public void stop();
}
public class Flash implements usb{
public void start(){
System.out.println("u盘开始工作");
}
public void stop(){
System.out.println("u盘停止工作");
}
}
之前学过,在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的 多实现 。并且,一个类能继承一个父类,同时实现多个接口。
接口的多继承
一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子接口继承父接口的方法。
所有父接口的抽象方法都有重写。
方法签名相同的抽象方法只需要实现一次
多态性
和类的相同
用接口定义 ,new新的接口实现的类
接口不能直接创建对象,但是可以通过接口名直接调用接口的静态方法和静态常量。
• 对于接口的抽象方法、默认方法,只能通过实现类对象才可以调用
– 接口不能直接创建对象,只能创建实现类的对象
JDK8中相关冲突
(1)当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法
(2)接口冲突(左右为难)
• 当一个类同时实现了多个父接口,而多个父接口中包含方法签名相同的默认方法时,
1.声明接口
2.选择保留其中一个,通过“ 接口名 .super. 方法名 "的方法选择保留哪个接口的默认方法。
总结
接口本身不能创建对象,只能创建接口的实现类对象,接口类型的变量可以与实现类
对象构成多态引用。
• 声明接口用 interface,接口的成员声明有限制:
– (1)公共的静态常量
– (2)公共的抽象方法
– (3)公共的默认方法(JDK8.0 及以上)
– (4)公共的静态方法(JDK8.0 及以上)
– (5)私有方法(JDK9.0 及以上)
• 类可以实现接口,关键字是 implements,而且支持多实现。如果实现类不是抽象类,就必须实现接口中所有的抽象方法。如果实现类既要继承父类又要实现父接口,那么继承(extends)在前,实现(implements)在后。
• 接口可以继承接口,关键字是 extends,而且支持多继承。
• 接口的默认方法可以选择重写或不重写。如果有冲突问题,另行处理。子类重写父接口的默认方法,要去掉 default,子接口重写父接口的默认方法,不要去掉 default。
• 接口的静态方法不能被继承,也不能被重写。接口的静态方法只能通过“接口名.静态方法名”进行调用
接口与抽象类对比
4.内部类
成员内部类
成员内部类作为 类的成员的角色 :
– 和外部类不同,Inner class 还可以声明为 private 或 protected;
– 可以调用外部类的结构。(注意:在静态内部类中不能使用外部类的非静态
成员)
– Inner class 可以声明为 static 的,但此时就不能再使用外层类的非 static 的
成员变量;
• 成员内部类作为 类的角色 :
– 可以在内部定义属性、方法、构造器等结构
– 可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部
类的父类和父接口无关
– 可以声明为 abstract 类 ,因此可以被其它的内部类继承
– 可以声明为 final 的,表示不能被继承
– 编译以后生成 OuterClass$InnerClass.class 字节码文件(也适用于局部内部类)
• 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
• 成员内部类可以直接使用外部类的所有成员,包括私有的数据
• 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的
局部内部类
编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名、$符号、
编号。
– 这里有编号是因为同一个外部类中,不同的方法中存在相同名称的局部内
部类
• 和成员内部类不同的是,它前面不能有权限修饰符等
• 局部内部类如同局部变量一样,有作用域
• 局部内部类中是否能访问外部类的非静态的成员,取决于所在的方法
匿名内部类
enum关键字
使用enum定义的类默认父类式java.lang.enum
不要再显式的定义父类
枚举类
String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
static 枚举类型[] values():返回枚举类型的对象数组。该方法可以很方便地遍历
所有的枚举值,是一个静态方法
static 枚举类型 valueOf(String name):可以把一个字符串转为对应的枚举类对
象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArg
umentException。
String name():得到当前枚举常量的名称。建议优先使用 toString()。
int ordinal():返回当前枚举常量的次序号,默认从 0 开始
5.注解
@author 标明开发该类模块的作者,多个作者之间使用,分割
@version 标明该类模块的版本
@see 参考转向,也就是相关主题
@since 从哪个版本开始增加的
@param 对方法中某参数的说明,如果没有参数就不能写
@return 对方法返回值的说明,如果方法的返回值类型是 void 就不能写
@exception 对方法可能抛出的异常进行说明 ,如果方法没有用 throws 显式抛出的异常就不能写
元注解
自定义注解
6.包装类
自定义包装类
public class MyInteger {
int value;
public MyInteger() {
}
public MyInteger(int value) {
this.value = value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
基本数据类型、包装类与字符串间的转换
(1)基本数据类型转为字符串
int a = 10;
//String str = a;// 错误的
String str = String.valueOf(a);
方式 2:更直接的方式
int a = 10;
String str = a + "";
(2)字符串转为基本数据类型
方式 1:除了 Character 类之外,其他所有包装类都具有 parseXxx 静态方法可
以将字符串参数转换为对应的基本类型,例如:
• public static int parseInt(String s) :将字符串参数转换为对应的 int 基本类型。
• public static long parseLong(String s) :将字符串参数转换为对应的 long基本类型。
• public static double parseDouble(String s) :将字符串参数转换为对应的double 基本类型。
方式 2:字符串转为包装类,然后可以自动拆箱为基本数据类型
• public static Integer valueOf(String s) :将字符串参数转换为对应的Integer 包装类,然后可以自动拆箱为 int 基本类型
• public static Long valueOf(String s) :将字符串参数转换为对应的 Long包装类,然后可以自动拆箱为 long 基本类型
• public static Double valueOf(String s) :将字符串参数转换为对应的Double 包装类,然后可以自动拆箱为 double 基本类型
注意:如果字符串参数的内容无法正确转换为对应的基本类型,则会抛java.lang.NumberFormatException 异常。
方式 3:通过包装类的构造器实现
int a = Integer.parseInt("整数的字符串");
double d = Double.parseDouble("小数的字符串");
boolean b = Boolean.parseBoolean("true 或 false");
int a = Integer.valueOf("整数的字符串");
double d = Double.valueOf("小数的字符串");
boolean b = Boolean.valueOf("true 或 false");
int i = new Integer(“12”);
其他API
//数据类型的最大最小值
Integer.MAX_VALUE 和 Integer.MIN_VALUE
Long.MAX_VALUE 和 Long.MIN_VALUE
Double.MAX_VALUE 和 Double.MIN_VALUE
//字符转大小写
Character.toUpperCase('x');
Character.toLowerCase('X');
//整数转进制
Integer.toBinaryString(int i)
Integer.toHexString(int i)
Integer.toOctalString(int i)
// 比较的方法
Double.compare(double d1, double d2)
Integer.compare(int x, int y)