Java面向对象 第5节 抽象类和接口
一、抽象类和抽象方法
- 区分抽象方法和普通方法
1)当一个方法被abstract修饰时,该方法成为抽象方法
2)抽象类所在的类必须定义为抽象类
3)抽象方法不会有具体的实现,而是在抽象类的子类中通过方法重写进行实现
4)定义抽象方法语法:
[访问修饰符] abstract <返回类型> <方法名>([参数类表])
5)区别:
抽象方法需要用abstract修饰,普通方法不需要;抽象方法没有方法体 - 区分普通类和抽象类
1)当一个类被abstract修饰时被称为抽象类
2)定义抽象类:abstract class <类名>{ }
3)区别:
抽象类需要用abstract修饰,普通类不需要;
普通类可以实例化,抽象类不能被实例化(但可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例) - 抽象类结构
public abstract class 类名{
修饰符 abstract 返回值类型 方法名();
修饰符 返回值类型 方法名(){
方法体
}
} - 抽象类和抽象方法的使用:
抽象方法只能定义在抽象类中,抽象类中可以包含抽象方法和普通方法及普通类包含的一切成员;
如果子类没有实现父类的所有抽象方法,则子类必须定义为抽象类;
没有抽象构造方法,也没有抽象静态方法;
抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用
package com.abstractInterface;
public abstract class Base {
//抽象类中可以没有抽象方法,但包含了抽象方法的类就必须被定义为抽象类
public abstract void method1();
public abstract void method2();
public void method3(){}
//没有抽象的构造方法
//public abstract Base(){}
//没有抽象的静态方法
//static abstract void method4(); public Base(){
System.out.println("父类的无参构造方法");
}
static void method4(){
System.out.print("静态方法表示类所特有的功能,这种功能的实现不依赖于类的具体实例,也不依赖于它的子类。因此,当前类必须为静态方法提供实现");
}
}
package com.abstractInterface;
//如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类
public abstract class Sub1 extends Base {
public void method1() {
System.out.println("重写父类的method1");
}
}
package com.abstractInterface;
//否则就必须实现父类的所有抽象方法
public class Sub2 extends Base {
public Sub2(){
System.out.println("子类的无参构造方法");
}
@Override
public void method1() {
System.out.println("重写父类的抽象方法method1");
}
@Override
public void method2() {
System.out.println("重写父类的抽象方法method2");
}
}
public class Test {
public static void main(String[] args) {
//抽象类不允许实例化
//Base base=new Base();
//抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用
//抽象类不能被实例化,但可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例
Base sub=new Sub2();
sub.method1();
sub.method4();
}
}
二、抽象类的优势
如图,设计一个抽象类,它有两个普通方法:飞行(弹射飞)和叫(嗷嗷),还有一个抽象方法攻击。分裂鸟和火箭鸟为这个抽象类的子类。
分裂鸟和火箭鸟都继承了父类的飞行和叫的方法,并重写了父类的攻击方法(两种鸟的攻击方式不同)。
总结:抽象类中已经实现的方法可以被其子类使用,使得代码可以被复用;同时提供了抽象方法,保证了子类具有自身的独特性
三、抽象类的局限性
"愤怒的小鸟"的游戏中,分裂鸟和火箭鸟的叫声都是“嗷嗷”,但是红色鸟和炸弹鸟飞出来后是“渣渣”叫,胖子鸟飞出来后干脆不叫,所以类图做如下修改:
此时,使用抽象类就会出现以下问题:1.叫的方法不在通用;2.子类继承鸟抽象类后,写出来的叫的方法可能会出现代码重复的情况,如红色鸟和炸弹鸟都是“喳喳“叫。
问题1,可以将叫方法给抽象方法,由其子类去具体实现;但这样会造成代码冗余的问题,如这里的分裂鸟和火箭鸟的叫方法也会一样,也就是问题2会更加突出。
为解决上述问题,最理想的方法是使用接口。
四、接口
生活中,常见的如USB接口有以下特点:USB接口本身没有实现任何功能;USB接口规定了数据传输的要求;USB接口可以被多种USB设备实现
- 接口概念
java中接口的作用和生活中的接口类似,他提供一种约定,是的实现接口的类早形式上保持一致。
如果抽象类中所有的方法都是抽象方法,就可以使用java提供的接口来表示,所以,从这个角度来讲,接口是一种特殊的”抽象类“,但两者语法和设计理念都不同 - 定义和实现一个简单的接口
接口是一个不能实例化的类型,需要注意:
1)接口:接口中不能有构造方法;
接口使用interface修饰符,访问修饰符只能是public,且可选;
接口成员可以是全局变量和公共的抽象方法(默认用 public 修饰);
接口中的变量都是静态常量(public static final),并必须指定初始值;
2)实现接口:实现接口用implements关键字;
实现接口的类必须实现接口中定义的所有抽象方法,否则必须定义为抽象类;
接口的实现类中允许包含普通方法;
实现类可以实现多各接口;package com.interfaceDemo;
/**
* USB接口。
* @author yu
*/
public interface UsbInterface {
/**
* USB接口提供服务。
*/
void service();
}package com.interfaceDemo;
/**
* U盘。
* @author yu
*/
public class UDisk implements UsbInterface {
public void service() {
System.out.println("连接USB口,开始传输数据。");
}
}package com.interfaceDemo;
/**
* USB风扇。
* @author yu
*/
public class UsbFan implements UsbInterface {
public void service() {
System.out.println("连接USB口,获得电流,风扇开始转动。");
}
}package com.interfaceDemo;
/**
* 测试类。
* @param args
*/
public class Test {
public static void main(String[] args) {
//1、U盘
UsbInterface uDisk = new UDisk();
uDisk.service();
//2、USB风扇
UsbInterface usbFan= new UsbFan();
usbFan.service();
}
} - 更复杂的接口
1)接口本身也可以继承接口:
[修饰符] interface 接口名 extends 父接口1,父接口2,....{
常量定义;
方法定义;
}
2)一个普通类只能继承一个父类,但能同时实现多个接口,也可以同时继承抽象类和实现接口:
class 类名 extends 父类名 implements 接口1,接口2,....{
类的成员;
}
package com.interfaceDemo;
/**
* 鸟叫的接口
* @author yu
*/
public interface ShoutAbility {
/**
* USB接口提供服务。
*/
public void shout(); //鸟叫的抽象方法
}
/****************************************/
package com.interfaceDemo;
/**
* 嗷嗷叫
* @author yu
*/
public class AoShout implements ShoutAbility {
public void shout() {
System.out.println("嗷嗷。。。。。");
}
}
/******************************************/
package com.interfaceDemo;
/**
* USB风扇。
* @author yu
*/
public class ZhaShout implements ShoutAbility {
public void shout() {
System.out.println("喳喳。。。。。");
}
}
/******************************************/
package com.interfaceDemo;
/*
* 无叫声
*/
public class NoShout implements ShoutAbility{
public void shout(){
//无叫声
}
}
/******************************************/
package com.interfaceDemo;
/*
* 鸟类
*/
public abstract class Bird {
ShoutAbility shoutAbility; //鸟叫的方式
String birdName; //鸟的名字
//构造方法,用来初始化鸟叫的行为
//构造方法
// public Bird(String birdName){
// this.birdName = birdName;
// }
public Bird(ShoutAbility shoutAbility,String birdName){
this.shoutAbility = shoutAbility;
this.birdName = birdName;
}
//叫
public void Shout(){
shoutAbility.shout();
}
//飞行
public void fly(){
System.out.println(this.birdName+"弹射飞!");
}
//攻击
public abstract void attrack();
}
/********************************/
package com.interfaceDemo;
/*
* 分裂鸟
*/
public class SplitBird extends Bird{
//构造方法
public SplitBird(ShoutAbility shoutAbility,String birdName){
super(shoutAbility,birdName);
}
//重写分裂方法
public void attrack(){
System.out.println("分裂攻击!");
} }
/************************************/
package com.interfaceDemo;
/*
* 火箭鸟
*/
public class RocketBird extends Bird{
public RocketBird(ShoutAbility shoutAbility,String birdName){
super(shoutAbility,birdName);
}
public void attrack(){
System.out.println("加速冲撞!");
}
}
/********************************************/
package com.interfaceDemo;
/*
* 红色鸟
*/
public class RedBird extends Bird{
//构造方法
public RedBird(ShoutAbility shoutAbility,String birdName){
super(shoutAbility,birdName);
}
//重写分裂方法
public void attrack(){
System.out.println("普通攻击!");
}
}
/******************************************/
package com.interfaceDemo;
/*
* 炸弹鸟
*/
public class BombBird extends Bird{
//构造方法
public BombBird(ShoutAbility shoutAbility,String birdName){
super(shoutAbility,birdName);
}
//重写分裂方法
public void attrack(){
System.out.println("爆炸攻击!");
}
}
/********************************************/
package com.interfaceDemo;
/*
* 胖子鸟
*/
public class FatBird extends Bird{
//构造方法
public FatBird(ShoutAbility shoutAbility,String birdNme){
super(shoutAbility,birdNme);
}
//重写分裂方法
public void attrack(){
System.out.println("扔蛋攻击!");
}
}
/********************************************/
package com.interfaceDemo; import java.text.Bidi; /**
* 测试类。
* @param args
*/
public class Test {
public static void main(String[] args) {
ShoutAbility shoutAbility = new AoShout(); //嗷嗷叫
ShoutAbility shoutAbility1 = new ZhaShout(); //喳喳叫
ShoutAbility shoutAbility2 = new NoShout(); //无叫声 Bird bird = new SplitBird(shoutAbility,"分裂鸟");
bird.fly();
bird.Shout();
bird.attrack(); Bird bird1 = new RocketBird(shoutAbility,"火箭鸟");
bird1.fly();
bird1.Shout();
bird1.attrack(); Bird bird2 = new RedBird(shoutAbility1,"红鸟");
bird2.fly();
bird2.Shout();
bird2.attrack(); Bird bird3 = new BombBird(shoutAbility1,"爆炸鸟");
bird3.fly();
bird3.Shout();
bird3.attrack(); Bird bird4 = new FatBird(shoutAbility2,"胖子鸟");
bird4.fly();
bird4.Shout();
bird4.attrack(); }
} - 面向对象的设计原则
1)摘取代码中变化的行为,形成接口
2)多用组合,少用继承
3)针对接口编程,不依赖于具体实现:具体代码实现中,体现在方法参数尽量使用接口,方法的返回值尽量使用接口,属性类型尽量使用接口等
4)针对扩展开放,针对改变关闭:项目中需求发生变化,应添加一个新的接口或类,而不要去修改源码
总的来说,接口和抽象类是实现堕胎的2种重要方式,是面向对象设计的基础
Java面向对象 第5节 抽象类和接口的更多相关文章
- Java面向对象进阶篇(抽象类和接口)
一.抽象类 在某些情况下,父类知道其子类应该包含哪些方法,但是无法确定这些子类如何实现这些方法.这种有方法签名但是没有具体实现细节的方法就是抽象方法.有抽象方法的类只能被定义成抽象类,抽象方法和抽象类 ...
- java面向对象基础(四):抽象类和接口
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 第二十八节:Java基础-进阶继承,抽象类,接口
前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...
- Java第五次作业--面向对象高级特性(抽象类和接口)
一.学习要点 认真看书并查阅相关资料,掌握以下内容: 掌握抽象类的设计 掌握接口的设计 理解简单工厂设计模式 理解抽象类和接口的区别 掌握包装类的应用 掌握对象的比较方法和比较器的使用 学习使用日期操 ...
- 牛客网Java刷题知识点之抽象类与接口
不多说,直接上干货! 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于它们的存在才赋予java强大的面向对象的能力. ...
- 夯实Java基础(十)——抽象类和接口
转载自:http://cmsblogs.com/ 该博主的网站上干货非常!非常!非常多(说三遍),强烈推荐大家前去学习. 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法 抽象类与接口是 ...
- Java基础系列4:抽象类与接口的前世今生
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 1.抽象类: 当编写 ...
- Java入门(一)——类、抽象类和接口
Java是一门面向对象语言,可以看出"对象"在Java有着举足轻重的位置.那么,"对象"从何而来呢?那必须是丈母娘造出来的,下面我们就先来说说这个丈母娘--类. ...
- Java编程思想学习(七) 抽象类和接口
1.抽象类和抽象方法 抽象方法:不完整的,仅有声明而没有方法体. abstract void f(); 抽象类:包含抽象方法的类.(若一个类包含一个或多个抽象方法,则该类必须限定为抽象的.) 1.用抽 ...
随机推荐
- 浅谈String中的==和对象中引用对象类型的==
@Test public void test02() { StringBuffer sb = new StringBuffer(); sb.append('a'); sb.append(11); Sy ...
- spring-data-redis HashOperations
spring-data-redis HashOperations /** * 从散列中删除给定的多个元素 * @param key 不能为null 散列的名称 * @param hashKeys 需要 ...
- Python自学:第三章 使用列表中的各个值
bicycles = ['trek','cannondale','redline','specialized'] message = "My first bicycle was a &quo ...
- CRM INBOX 查询结果增强字段
参考:https://blogs.sap.com/2013/03/25/how-to-integrate-new-result-list-attributes-into-the-agent-inbox ...
- [luogu P3648] [APIO2014]序列分割
[luogu P3648] [APIO2014]序列分割 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序 ...
- 使用Python-Libvirt GUI 实现KVM 虚拟机 界面化管理
一.KVM环境的搭建 1.安装VMware(略) 2.在VMware中安装Linux系统(略,Ubuntu16.04) 打开支持虚拟化 网络选择桥接模式 3.安装qemu apt-get instal ...
- WIFI 万能钥匙万玉权:团队之中要有跨三界之外的“闲人” [转]
在团队规模较小时,很多事情都可以变得特别简单.比如架构的选择,大部分情况下,最初的架构越简单越好,随着业务的演进,架构才不断完善. 连尚网络经历了从几人到上百人的管理过程,其自主创新研发的产品 W ...
- vscode 创建.net core mvc
cd 进一个文件夹 1,创建一个sln 工程文件 [ dotnet new sln -n Demo1 ] 2,创建一个mvc项目 [ dotnet new mvc -n Demo1.Web ] 3, ...
- vuex实现原理
一.Store的层次结构 Store,负责管理整个数据访问.修改等: 提高API: State,数据结构: 所有的getters.mutations,全部都注册到store里:结构大概是: { 'xx ...
- Centos7配置TiDB集群
一:各模块属性 模块名称 状态 建议实例数 功能 负载均衡组件 TiDB 无状态 2 接收SQL请求,处理SQL相关逻辑,并通过PB找到存储数据的TiKV地址 LVS.HAProxy.F5 PB 集群 ...