面向对象高级特性
抽象
为什么会有抽象类
当子类中都有一个共同的方法,每一个子类都有不同的实现,在父类中又要体现所有子类的共同的特点,所以要体现有这个方法,但是在父类中又无法给出具体的实现,那么这个时候就需要把这个方法声明为抽象的,而包含抽象方法的类,必须是抽象类
某个父类仅仅是表示一个抽象的概念,不希望它被实例化,这个时候父类中可能没有抽象方法,但是我们也把它声明为抽象类
如何声明抽象类
//语法格式 [public/缺省] abstract class 类名{ }
如何声明抽象方法
//语法格式 [public/protected/缺省] abstract 返回值类型 方法名([形参列表]); *注意:抽象方法是不能private,static,final修饰的
抽象类的特点
(1)抽象类不能实例化
(2)抽象类可以包含抽象方法,也可以没有抽象方法。
如果一个类有抽象方法,那么这个类必须是抽象类,
如果一个抽象类没有抽象方法,那么它的用意是不想实例化,用它仅仅表示一个抽象的概念。
(3)抽象类生来就是用来被继承的,那么子类在继承它的时候,必须重写(实现)抽象父类的抽象方法,
否则该子类也得是抽象类。
(4)抽象类的变量与子类的对象构成多态引用。
(5)抽象类除了不能实例化,可以包含抽象方法,其他的和非抽象类是一样的,
可以有成员变量(类变量、实例变量)、构造器、代码块(静态代码块和非静态代码块)
方法(静态方法、非静态方法)
抽象类不能实例化,为什么要有构造器呢?
子类在继承该类时,一定要调用它的构造器,为属性初始化。
因为构造器的作用有两点
(1)和new一起创建对象
(2)为属性初始化
接口
接口即代表行为标准,功能标准
如何声明一个接口?
//语法格式 [public/缺省] interface 接口名{ }
如何实现接口?
//语法格式 [public/缺省] class 子类名 [extends 父类名] implements 接口名1,接口名2。。。{ //要实现接口的所有抽象方法 }
接口的特点
JDK1.7
JDK1.7: (1)接口不能实例化 (2)接口只能有全局静态的常量和公共的抽象方法 (3)接口中不能有构造器,因为它没有属性需要初始化,又不能创建对象 (4)接口生来用来被实现的,那么实现类(像子类)在实现它时,必须实现(和重写要求一样)接口的 所有抽象方法,否则该实现类也得是抽象类 (5)一个类可以同时实现多个接口 (6)一个类还可以继承父类又实现接口,但是必须先继承后实现 (7)接口与接口之间是继承关系,一个接口可以继承多个接口 (8)接口与实现类的对象之间构成多态引用
其他的和JDK1.7一样,不一样的是:
JDK1.8之后,接口中除了全局静态的常量和公共的抽象方法以外,可以有静态方法和默认方法
接口中的默认方法
当接口的所有实现类,对这个方法的实现是一样的,这个方法就设计在接口中,设计为静态方法
如何调用:接口名.方法
接口中的静态方法
当接口的大多数实现类,对这个方法的实现是一样,那么这个方法的实现就可以在接口中提供默认实现,如果某个实现类觉得他不合适,只需要重写它即可
如何调用
实现类外:实现类对象.方法
实现类中:如果实现类要重写该默认方法,但是又想调用接口中的默认实现
接口名.super.方法
什么情况下需要重写
接口中的默认实现不适合该实现类
必须重写:
一个类同时实现了多个接口,而多个接口中都相同的默认方法(方法名和形参列表都相同),这个时候实现类必须做出选择,要重写,如果需要保留其中一个的话,通过接口名.super.方法,保留它的默认实现
类优先原则
当一个类继承了父类,又实现了接口,而且父类中的某个方法与接口中的默认方法一样(方法名和形参列表),默认保留的是父类中的方法实现
枚举
枚举是指某个类型的对象是有限个,在类型中一一创建并列举它的对象
如何声明
[修饰符] enum 枚举类型名{ 常量对象列表 } [修饰符] enum 枚举类型名{ 常量对象列表; 其他成员; }
特点
(1)枚举类型中的构造器都是私有化
(2)常量对象列表必须在首行,如果常量对象列表后面还有其他的代码,那么要用;结束
(3)枚举类型不能继承别的类型,因为它默认继承java.lang.Enum
它有一些方法
name() 返回常量对象名
ordinal() 返回常量对象的序号,从0开始
实现了java.lang.Comparable接口,重写compareTo(),按照常量对象的顺序排序 如果自己的枚举类中不适合,可以重写
toString() 返回常量对象名 可以重写
API中没有的方法
枚举类型名.values() 返回枚举常量对象组成的数组
枚举类型名.valueOf(常量对象的名称) 返回某一个指定的对象
(4)switch对枚举加入支持
switch(枚举类型表达式){ case 常量对象名1: 语句; [break;] case 常量对象名2: 语句; [break;] case 常量对象名3: 语句; [break;] default: 语句; [break;] }
注解
概念
代码级别的注释
给代码读取的注释
不同普通的注释(给人看的) 单行注释 和 多行注释
四种
1、编译器的格式检查
(1)@Override:告知编译器对该方法按照“重写”的要求进行格式检查
(2)@SuppressWarnings:告知编译器抑制警告
(3)@Deprecated:告知编译器某个元素是已过时,有人用了就弹出警告
2、文档注释
(1)@version 指定当前版本
(2)@author 指定作者
(3)@since 指定从那个版本开始
(4)@see 另请参阅
(5)param
指定当前方法的形参信息
可以多个
只有方法有形参才能标记
格式:@param 形参名 形参类型 形参的描述信息
(6)@return
指定当前方法的返回值信息
一个方法只能有一个,如果方法是void,就不能标记@return
格式:@return 返回值的类型 返回值的描述
(7)@exception
指定当前方法抛出异常的信息
可以多个
只有方法抛出异常才能标记
格式:@exception 异常类型 异常的描述
结合javadoc.exe
3、JUnit的单元测试
白盒测试,程序员自己的测试,在程序员知道当前的代码的功能的
@Test
加在方法上
这个方法必须是公共的,无参,无返回值,不能是static
@Before:在@Test标记的方法之前运行
@After:在@Test标记的方法之后运行
4、各大框架等替代配置文件
注解的三个部分
1.声明:一般都是别人声明好的
2.使用
3.读取
例如:@Override等,由javac.exe
例如:@author,@param等,由javadoc.exe
例如:@Test等,由JUnit相关的类读取
例如:@WebServlet等,由Tomcat读取
如果自己要读取,通过反射,而且只能读取@Retention(RetentionPolicy.RUNTIME)
注解的声明
(1)无参
//声明格式 @元注解 [修饰符] @interface 注解名{} //使用格式 @注解名
(2)有参
//声明格式 @元注解 [修饰符] @interface 注解名{ 配置参数 } //配置参数 格式:数据类型 参数名(); 一个注解可以有多个配置参数 配置参数可以有默认值 数据类型 参数名() default 默认值; 配置参数的类型有要求 类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组
//使用格式 @注解(参数赋值) 如果配置参数有默认值,那么可以在使用时不需要赋值 如果配置参数只有一个,而且名称是value,那么可以在赋值时省略value= 参数赋值的格式 参数名 = 参数值 如果多个使用,分割 如果配置参数的类型是数组类型 如果只有一个元素,那么可以省略{} 如果是多个元素,那么需要{}
元注解
@Target
指定某个注解它的使用目标位置
如何指定它
它配置参数的类型是一个枚举数组 ElementType枚举类型 常量对象有:TYPE, FIELD,METHOD等
配置参数的名称是value
如果只有一个 @Target(ElementType.METHOD)
如果是多个 @Target({ElementType.METHOD,ElementType.FIELD,。。。。})
@Retention
指定某个注解的生命周期,可以保留到什么阶段
如何指定它
它的配置参数的类型是一个枚举类型 RetentionPolicy类型 常量对象有三个 SOURCE,CLASS,RUNTIME
配置参数的名称是value
@Retention(RetentionPolicy.RUNTIME)
@Documented 表示是否javadoc读取
@Inherited 是否被子类继承
在java.lang.annotation包
标签:实现,高级,接口,面向对象,枚举,特性,类型,抽象类,方法 From: https://www.cnblogs.com/woniupa/p/17169778.html