抽象方法和抽象类
通达信行情接口服务器,接口只能继承多个通达信行情接口服务器,接口,接口不能继承类,也不能实现其他接口。
接口和抽象类都可以包含抽像方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化。使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。final修饰的局部变量在定义时没有指定默认值,则应在后面的代码中对该final变量赋初始值,但只能赋值一次,不能重复赋值。如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能对该变量赋值。
接口编程案例
易于系统的维护。
抽象类和接口的区别
SpeedMeter类中提供了速度表的通用算法,但一些具体的实现细节则推迟到其子类CerSpeedMeter类中实现。这是一种典型的模板模式。
定义抽象方法语法
[访问修饰符] abstract 返回类型 方法名([参数列表])
抽象父类仅定义使用的某些方法,将不能实现的部分抽象成抽象方法,留给其子类实现。
在该dao包中定义一个实现UserInfoDao的用户信息维护UserInfoDaoImpl,该类分别实现接口中所有的抽象方法。
public class UserInfoDaoImpl implements UserInfoDao { //实现用户信息维护接口
public void saveUser(UserInfo user) {
System.out.println('执行新增方法');
System.out.println('姓名:'+ user.getName() +' 年龄:'+ user.getAge() + ' 生日:'+ user.getBirthday() + ' 家庭地址:'+ user.getAddress());
}
public void updateUser(UserInfo user) {
System.out.println('执行更新方法');
}
public void deleteUser(UserInfo user) {
System.out.println('执行删除操作');
}
}
创建dto包,在该包中定义类UserInfo用于封装用户信息。
public class UserInfo { //用户实体类
private String name;
private int age;
private String birthday;
private String address;
//省略属性的setter和getter方法
}
示例:在速度表应用上使用模板设计模式
final修饰的方法不可以被重写。如果不允许子类重写父类的某个方法,则可以使用final修饰该方法。
在UserInfoAccess类定义服务方法service()实现主体业务。
public class UserInfoAccess {
private UserInfoDao userInfoDao=new UserInfoDaoImpl();
public void service(){
System.out.println('请选择操作【1】添加【2】修改【3】删除');
Scanner input=new Scanner(System.in);
String state=input.next();
if('1'.equals(state)){
userInfoDao.saveUser();
}else if('2'.equals(state)){
userInfoDao.updateUser();
}else if('3'.equals(state)){
userInfoDao.deleteUser();
}
}
}
public class UserMain{
public static void main(String[] args) {
new UserInfoAccess().service();
}
}
示例:在形继承关系中使用抽象类和抽象方法
接口编程实例
//抽象类形Shape:
public abstract class Shape { // 抽象类 图形
private String color;
// 定义一个计算周长的抽象方法
public abstract double calcPerimeter();
// 定一个返回图形子类型的方法
public abstract String getType();
// 有参构造方法
public Shape(String color){
this.color=color;
System.out.println('---执行了Shape类的构造方法---');
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
实践练习
语法:
[访问修饰符] interface 接口名 extends 父接口1,[父接口2,...]
//子类三角形Triangle:
public class Triangle extends Shape{ //子类 三角形
private double x,y,z; //定义三角形边
public Triangle(String color,double x,double y,double z) {
super(color); //调用父类构造器
this.setSide(x, y, z);
}
public void setSide(double x,double y,double z){//设置三角形三边
if(x>y+z || y>x+z || z>x+y){
System.out.println('三角形两边之和必须大于第三边');
return ;
}
this.x=x, this.y=y,this.z=z;
}
public double calcPerimeter() {//重写父类计算周长方法
return x+y+z;
}
public String getType() {//重写父类获取图形类型方法
return '三角形';
}
}
面向接口编程的优点:
//抽象父类速度表SpeedMeter,该抽象类为模板类
public abstract class SpeedMeter { //抽象父类速度表,该抽象类为模板类
private double trunRate; //转速
//将返回车轮半径的方法定义为抽象方法
public abstract double getRedius();
//定义计算速度的通用算法
public double getSpeed(){
//速度=车轮半径*2*π*转速
return 2*3.14*getRedius()*getTrunRate();
}
public double getTrunRate() {
return trunRate;
}
public void setTrunRate(double trunRate) {
this.trunRate = trunRate;
}
}
final关键字可以用于修饰类、变量和方法。final修饰变量时,表示该变量一旦获得了初始值就不可能被改变,final修饰的类不能被继承,final修饰的方法可以被继承但不能被重写。final意味着终极。
抽象类不能被实例化,只能作为父类继承。从多个具有相同特征的类中抽象出一个抽象类,以该抽象类作为其子类的模板。
接口中不包含构造器,而抽象类中可以包含构造器,抽象类中的构造器并不用于创建对象,而是让其子类调用这些构造器来完成抽象类的初始化操作。
//子类圆形Circle:
public class Circle extends Shape { //子类 圆形
private double r;//半径
public Circle(String color,double r) {
super(color);
this.r=r;
}
public double calcPerimeter() {//重写父类计算周长方法
return 2*Math.PI*r;
}
//重写父类获取图形类型方法
public String getType() {
return '圆形';
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
abstract不能用于修饰属性,不能用于修饰局部变量,也不能用于修饰构造器。
final关键字可以用于修饰类、变量和方法。final修饰变量时,表示该变量一旦获得了初始值就不可能被改变,final修饰的类不能被继承,final修饰的方法可以被继承但不能被重写。
相同点:
避免子类设计的随意性:
语法:
[访问修饰符] class 类名 implements 接口1,[接口2,...]
抽象类不能被实例化,只能作为父类继承。
什么是面向接口编程?
系统接收到用户输入的指令后,给出相应的提示信息。
接口的实现
final修饰符
不同的形子类形计算周长的方式大相径庭,所以导致Shape类的calcPerimeter()方法无法运用某个固定的计算形周长的公式。可以将calcPerimeter()方法定义为抽象方法,抽象方法没有具体的方法实现,该方法必须由其继承的子类重写,这样该方法就起到了约束规范的作用,又不影响类最初的设计思路。
示例:设计一个具有输入功能,并且防水、防尘功能的键盘,以及一个防水、防尘和防盗功能的防盗门
public interface Input { //输入接口
//定义输入的标准,由其实现类实现具体的实现细节
public abstract void input(); // abstract 可省略
}
public interface Function { //功能接口
//接口只能定义常量, 而且必须是静态常量
public static final String DEEP='30米';//防水深度
//防尘指数
int INDEX=5; //接口中的常量默认是公有的、静态、终极的
//防水功能
public abstract void waterproof();
//防尘功能
void dust(); //接口中的方法默认是公有的、抽象的
}
public interface ExtendsFunction extends Function { //扩展功能
void antiTheft(); //防盗
}
public class AntitheftDoor implements ExtendsFunction { //防盗门实现扩展功能接口
//实现防水功能
public void waterproof() {
System.out.println('我是防盗门采用高科技的防水技术,防水深度:'+DEEP);
}
//实现防尘功能
public void dust() {
System.out.println('我是防盗门采用纳米防尘技术防尘,防尘指数:'+INDEX+'颗星');
}
//实现防盗功能
public void antiTheft() {
System.out.println('我是防盗门采用密码匹配防盗技术');
}
}
public class Keyboard implements Function,Input{ //键盘类实现功能接口和输入接口
//实现防水功能
public void waterproof() {
System.out.println('我是键盘采用特殊的密封屏蔽技术实现防水,防水深度:'+DEEP);
}
//实现防尘功能
public void dust() {
System.out.println('我是键盘采用全硅胶材料实现防尘功能,防尘指数:'+INDEX+'颗星 ');
}
//实现Input接口中的输入功能
public void input() {
System.out.println('我是键盘可以将敲击键盘上的数据输入到计算机中');
}
}
public class Tset{
public static void main(String[] args) {
//创建键盘对象
Keyboard keyboard=new Keyboard();
keyboard.dust();//调用键盘的防尘方法
keyboard.waterproof();//调用键盘的防水方法
keyboard.input();//调用输入方法
System.out.println('------------------------------------');
//创建防盗门对象
AntitheftDoor antitheftDoor=new AntitheftDoor();
antitheftDoor.antiTheft();//调用防盗门的防盗方法
antitheftDoor.dust();//调用防盗门的防尘方法
antitheftDoor.waterproof();//调用防盗门的防水方法
}
}
模板模式基本规则:
总结:
创建business包,在该包中定义UserInfoAccess类,在该类定义UserInfoDao对象属性,该值为实现UserInfoDao接口的具体对象。
一个抽象类中可以不定义抽象方法,但是只要类中有一个抽象方法,则该类一定是抽象类。
示例:演示final成员变量使用
接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
接口
父类中包含需要调用其他依赖的方法,这些被调方法既可以由父类实现,也可以由其子类实现。父类中提供的方法仅定义了一个通用算法,需要具体子类辅助实现。
示例:演示final方法使用
public class Bank {
//将该方法定义为final,不允许子类重写该方法
public final void LowerInterestRates(){
System.out.println(“央行按照宏观经济情况进行统一降息,各银行按照国家标准统一执行');
}
}
public class ChinaBank extends Bank{
//如果子类重写父类的fianl()方法,程序在编译时将报错
public final void LowerInterestRates(){
}
}
抽象类
如何定义形类计算周长的通用方法?
final修饰符修饰的类称为最终类,最终类不能有子类。final类通常具有固定作用,用于完成某种标准功能。final不能被继承以达到不能被修改的目的。
当客户需求变化时,只需编写该业务逻辑的新的实现类,通过更改配置文件中该接口的实现类就可以完成需求,而不需要改写现有代码,从而减少对系统的影响。
接口中只能定义静态常量,不能定义普通变量,或非静态的常量,而抽象类中则可以定义不同的属性,也可以定义静态的属性。
示例:演示final局部变量使用
接口中不能定义静态方法,而抽象类中可以定义静态方法。
创建dao包,在该包中定义一个维护用户信息的接口UserInfoDao,在该接口中定义3个抽象方法,它们的功能分别是删除用户、更新用户信息和保存用户。
public interface UserInfoDao { //维护用户信息接口
public abstract void deleteUser(UserInfo user);
public abstract void updateUser(UserInfo user);
public abstract void saveUser(UserInfo user);
}
Java中的接口同生活中的接口一样,体现的是一种能力。
面向接口编程就是先把客户的业务逻辑线提取出来作为接口,接口业务的具体实现通过该接口的实现类来完成。
final局部变量
抽象类的作用
不同点:
//子类汽车速度表CarSpeedMeter
public class CarSpeedMeter extends SpeedMeter{ //子类汽车速度表
//重写父类的获取半径的方法
public double getRedius() {
return 2.0;
}
public static void main(String[] args) {
//创建CarSpeedMeter对象
CarSpeedMeter csm=new CarSpeedMeter();
csm.setTrunRate(15);//设置转速
System.out.println('当前汽车时速='+csm.getSpeed()+'公里/小时');
}
}
实践练习
实践练习
抽象类和抽象方法规则:一个抽象类中可以不定义抽象方法,但是只要类中有一个抽象方法,则该类一定是抽象类。抽象类不能被实例化,即不能被new创建一个实例对象。如果一个子类继承一个抽象类,则子类需要通过覆盖的方式来重写该抽象类中的所有抽象方法。如果子类没有完全重写抽象父类中所有的抽象方法,则子类仍是抽象的。抽象方法可以与public、protected复合使用,但不能与final、private和static复合使用。
抽象类作为多个子类的通用模板。子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。编写一个抽象父类,父类提供多个子类的通用方法,并且将一个或多个方法留给其子类实现,这就是一种模板模式。
接口的定义
一个类最多只能有一个直接父类,包括抽象类,而一个类可以实现多个接口。通过实现多个接口可以弥补Java单继承的不足。
要求用户按照系统在控制台中的提示信息,做出相应的选择。
易于系统的扩展。
实践练习
使用面向接口编程实现一个简易的用户管理系统
示例:演示final类使用
public final class Bank { // final类
public void LowerInterestRates(){
System.out.println(“央行按照宏观经济情况进行统一降息,各银行按照国家标准统一执行');
}
}
public class ChinaBank extends Bank{ //报错,final类不能有子类
}
}
main方法
public static void main(String[] args) { // 测试
Shape triangle=new Triangle('红色', 3, 4, 5);
Shape circle=new Circle('红色', 4);
System.out.println(triangle.getType()+' 周长='+triangle.calcPerimeter());
System.out.println(circle.getType()+' 周长='+circle.calcPerimeter());
}
体现了模板模式的设计理念:
定义抽象类语法
[访问修饰符] abstract class 类名
final成员变量
对于final修饰的成员变量而言,一旦赋初始值,就不能被重新赋值。final修饰的类属性只能在静态初始化块或声明该属性时指定初始值。final修饰的实例属性只能在构造方法或声明该属性时指定初始值。
降低程序的耦合性。在程序中紧密的联系并不是一件好的事情,因为两种事物之间联系越紧密,更换其中之一的难度就越大。
接口中只能包含抽象方法,而抽象类则完全可以包含普通方法。
举例:生活中的接口
文章为作者独立观点,不代表股票交易接口观点