多态以及抽象接口
多态
1.什么是多态
具有多种形态的行为被称为多态,简单来说,多态是具有表现多种形态的能力的特征,同一个实现接口,使用不同的实例而执行不同操作
2.类的权限分为两种
- 公共类(public)
- 默认类(default)
注意:默认类不能出本类
3.多态存在的三个必要条件
- 要有继承,有三种级别可供选择
— 父类-子类(is-a)
—抽象类-实现类(is-a)
—接口-实现类(like-a) - 要有重写
- 父类引用指向子类对象
4.运行时多态与非运行时多态
(1)非运行时多态(还没有进main)
在main程序入口之前定义的一个父类引用子类指向对象的方法,然后在main中调用方法创建对象
(2)运行时多态:在main中定义父类引用子类指向对象
范例
编写老师类,教师来自北京中心,初始化时,只需提供老师姓名,需要提供所在中心名称及教员姓名
老师类的基础上,开发一个类代表学校,负责对各老师进行评估,评估内容包括:
1、老师的自我介绍
2、老师的授课
升级老师类,增加一种新类型:DBTeacher,该类型的老师专门负责教授数据库,要求如下:
属性:姓名、所属中心
方法:授课(启动Sql Server、实施理论课授课)、自我介绍
同时,学校也负责对这类老师进行评估
/**
*Teacher.java(定义老师的两种基本方法:自我介绍和授课行为)
*/
package extendyes;
public class Teacher {
//隶属中心
private String school;
//姓名
private String name;
/**
* 创建对象并初始化成员变量
* @param school 要设置的中心
* @param name 要设置的姓名
*/
public Teacher(String school,String name){
this.school=school;
this.name=name;
}
/**
* 自我介绍
*/
public void introduction(){
System.out.println("大家好!我是来自于"+this.school+"中心的"+this.name+"老师");
}
/**
* 授课
*/
public void giveLesson(){
System.out.println("实施理论课教授...");
}
}
/**
*JavaTeacher.java(初始化java老师的基本属性,重写两种方法)
*/
package extendyes;
/**
* JavaTeacher 继承于 Teacher
* super:当前对象的直接父类的引用
* @author Administrator
*
*/
public class JavaTeacher extends Teacher {
/**
* 初始化隶属中心和姓名两个属性
* @param school 要设置的隶属中心
* @param name 要设置的姓名
*/
public JavaTeacher(String school, String name) {
//调用父类的构造方法,来完成我的初始化工作
super(school, name);
}
/**
* 授课 父类:被重写方法 子类:重写方法
* 两者应保持一致
*/
public void giveLesson(){
System.out.println("打开Eclipse...");
//调用父类的授课方法
super.giveLesson();
}
}
/**
*DotNetTeacher.java(初始化DotNet老师的基本属性,重写两种方法)
*/
package extendyes;
public class DotNetTeacher extends Teacher {
/**
* 初始化成员变量
* @param school 要设置的隶属中心
* @param name 要设置的姓名
*/
public DotNetTeacher(String school,String name){
//调用父类的方法完成初始化
super(school,name);
}
public void giveLesson(){
System.out.println("打开VS2015...");
//调用父类的授课方法
super.giveLesson();
}
}
/**
*DBTeacher.java(初始化DBT老师的基本属性,重写两种方法)
*/
package extendyes;
public class DBTeacher extends Teacher {
/**
* 初始化成员变量
* @param school 要设置的隶属中心
* @param name 要设置的姓名
*/
public DBTeacher(String school, String name) {
//调用父类的方法
super(school, name);
}
@Override
public void giveLesson() {
System.out.println("打开SqLServer");
//调用父类的授课方法
super.giveLesson();
}
}
/**
*School.java(多态方法评价各种类型的老师的两种行为)
*/
package polymorphicyes;
import extendyes.DBTeacher;
import extendyes.DotNetTeacher;
import extendyes.JavaTeacher;
public class School {
/**
* 对java老师进行评价
* @param jt 要评价的java老师
*/
public static void judge(JavaTeacher jt){
//自我介绍
jt.introduction();
//授课
jt.giveLesson();
}
/**
* 对象.net老师进行评价
* @param dnt 要评价的.net老师
*/
public static void judge(DotNetTeacher dnt){
//自我介绍
dnt.introduction();
//授课
dnt.giveLesson();
}
/**
* 对象DB老师进行评价(多态的方法)
* @param dbt 要评价的DB老师
*/
public static void judge(DBTeacher dbt){
//自我介绍
dbt.introduction();
//授课
dbt.giveLesson();
}
public static void main(String[] args) {
//对java老师进行评价
judge(new JavaTeacher("北京", "张三"));
System.out.println("----------------------");
//对.net老师进行评价
judge(new DotNetTeacher("西安", "李四"));
System.out.println("----------------------");
//对DB老师进行评价
judge(new DBTeacher("武汉", "王五"));
}
}
效果如下
抽象类
1.抽象类的应用场景
—我们在描述一类事物的时候,发现该种事物确实存在着某种行为,但是这种行为目前是不具体的,那么我们可以抽取这种行为 的声明,但是不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类。
2.抽象类的关键词
abstract
抽象类不能有对象(new 对象),因为他的行为是不具体的,但是它的实现类可以new对象,而且实现抽象类的时候,强制要重写抽象类中的抽象方法
范例
以小狗和鱼儿的前进方式为例,进行简单的输出,class Animal是定义的一个抽象类方法,模拟各种动物的前进方式,class Dog和class Fish是抽象类的实现类,里面应该定义具体的前进方法(run()),最后在测试类中使用了多态的方法创建两个对象,调用多态方法(showRun(Animal a))
/**
*TestAnimal.java(显示小狗和鱼儿的前进方式)
*/
package test;
/**
* 抽象类
* @author Administrator
*
*/
abstract class Animal{
/**
* 动物的前进方式(抽象方法)
*/
public abstract void run();
}
/**
* 实现类(继承于抽象类)
* @author Administrator
*
*/
class Dog extends Animal{
@Override
public void run() {
System.out.println("用4条腿跑...");
}
}
/**
* 实现类
* @author Administrator
*
*/
class Fish extends Animal{
public void run(){
System.out.println("用尾巴游来游去...");
}
}
public class TestAnimal {
/**
* 显示各种动物的移动方式(多态的方法)
* @param i 要显示移动方式的动物
*/
public static void showRun(Animal a){
a.run();
}
public static void main(String[] args) {
//显示狗的跑
showRun(new Dog());
//显示鱼的游动
showRun(new Fish());
}
}
效果如下
Java接口
1.什么是java接口
(1)一个Java接口是一些方法特征的集合,但没有方法的实现
(2)Java接口中定义的方法在不同的地方被实现,可以具有完全不同的行为
(3)可以使用Java接口标识类型(interface)
(4)运行时,根据实际创建的对象类型调用相应的方法实现
注意:抽象是实际存在的,接口是程序员为了方便设计构造的
2.为什么需要Java接口
每增加一种新类型,都需要增加相应的print(类型名称 var)方法
——程序的可扩展性及可维护性极差
——这不符合系统的要求
通过Java接口,我们同样可以享受到多态性的好处,大大提高了程序的可扩展性及可维护性
3.面向接口编程
开发系统时,主体构架使用接口,接口构成系统的骨架,这样就可以通过更换接口的实现类来更换系统的实现
4.接口和抽象类的区别
语法上的区别:
(1)抽象类里可以有构造方法,而接口内不能有构造方法。
(2)抽象类中可以有属性,而接口中也可以有属性,但只能是常量。。
(3)抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。
(4)抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
(5)抽象类中可以包含静态方法,接口内不能包含静态方法。
(6)抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。
(7)一个类可以实现多个接口,但只能继承一个抽象类。
5.00思想总结
oo基本思想特征 | 定义 | 具体实现方式 | 优势
oo基本思想特征 | 定义 |
---|---|
封装 | 隐藏实现细节,对外提供公共的访问接口 |
继承 | 从一个已有的类派生出新的类,子类具有父类的一般特征,以及自身特殊的特性 |
多态 | 同一个实现接口,使用不同的实例而执行不同操作 |
具体实现方式 | 优势 |
属性私有化、添加公有的setter、getter方法 | 增强代码的可维护性、健壮性 |
继承需要符合的关系:is-a | 1、实现抽象(抽出像的部分) 2、增强代码的可复用性 |
通过Java接口/继承来定义统一的实现接口;通过方法重写为不同的实现类/子类定义不同的操作 | 增强代码的可扩展性、可维护性 |
范例
定义一个飞行模式,模拟小鸟、飞机、火箭的飞行方式,使用接口的方法返回一个字符串语句
/**
*Flyer.java(抽象的一种飞行方法)
*/
package polymorphicyes;
/**
* interface里面都是抽象的方法,没有方法体,没有大括号
* @author Administrator
*
*/
public interface Flyer {
//抽象方法
public void fly();
}
/**
*Bird.java(实现小鸟类的飞行方式,重写fly()方法)
*/
package polymorphicyes;
/**
* Bird 实现Flyer接口
* @author Administrator
*
*/
public class Bird implements Flyer {
@Override
public void fly() {
System.out.println("用翅膀飞行...");
}
}
/**
*Plane.java(实现飞机类的飞行方式,重写fly()方法)
*/
package polymorphicyes;
/**
* implements:实现接口
* Plane 实现Flyer接口
* @author Administrator
*
*/
public class Plane implements Flyer {
@Override
public void fly() {
System.out.println("用发动机飞行...");
}
}
/**
*Rocket.java(实现火箭类的飞行方式,重写fly()方法)
*/
package polymorphicyes;
/**
* Rocket 实现Flyer接口
* @author Administrator
*
*/
public class Rocket implements Flyer {
@Override
public void fly() {
System.out.println("用空气动力飞行...");
}
}
/**
*TestFlyer.java(测试类,使用多态的方法,显示各种类型的飞行方式,创建各类的实例对象)
*/
package polymorphicyes;
public class TestFlyer {
/**
* 非运行时多态
* 显示各种能飞的飞行
* 父类(抽象类/接口)引用
* @param flyer 要显示各种飞行的事物
*/
public static void fly(Flyer flyer){
flyer.fly();
}
public static void main(String[] args) {
//显示飞机的飞行
fly(new Plane());
//显示鸟的飞行
fly(new Bird());
//显示火箭的飞行
fly(new Rocket());
}
}