一、抽象类和抽象方法

  1. 区分抽象方法和普通方法
    1)当一个方法被abstract修饰时,该方法成为抽象方法
    2)抽象类所在的类必须定义为抽象类
    3)抽象方法不会有具体的实现,而是在抽象类的子类中通过方法重写进行实现
    4)定义抽象方法语法:
    [访问修饰符]  abstract  <返回类型> <方法名>([参数类表])
    5)区别:
      抽象方法需要用abstract修饰,普通方法不需要;抽象方法没有方法体
  2. 区分普通类和抽象类
    1)当一个类被abstract修饰时被称为抽象类
    2)定义抽象类:abstract  class <类名>{    }
    3)区别:
      抽象类需要用abstract修饰,普通类不需要;
           普通类可以实例化,抽象类不能被实例化(但可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例)
  3. 抽象类结构
    public abstract  class 类名{
        修饰符  abstract  返回值类型 方法名();
        修饰符  返回值类型  方法名(){ 
             方法体
        }
    } 
  4. 抽象类和抽象方法的使用:
    抽象方法只能定义在抽象类中,抽象类中可以包含抽象方法和普通方法及普通类包含的一切成员;
    如果子类没有实现父类的所有抽象方法,则子类必须定义为抽象类;
    没有抽象构造方法,也没有抽象静态方法;
    抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用
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设备实现

  1. 接口概念
    java中接口的作用和生活中的接口类似,他提供一种约定,是的实现接口的类早形式上保持一致。
    如果抽象类中所有的方法都是抽象方法,就可以使用java提供的接口来表示,所以,从这个角度来讲,接口是一种特殊的”抽象类“,但两者语法和设计理念都不同
  2. 定义和实现一个简单的接口


    接口是一个不能实例化的类型,需要注意:
    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();
    }
    }
  3. 更复杂的接口
    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(); }
    }

      

  4. 面向对象的设计原则
    1)摘取代码中变化的行为,形成接口
    2)多用组合,少用继承
    3)针对接口编程,不依赖于具体实现:具体代码实现中,体现在方法参数尽量使用接口,方法的返回值尽量使用接口,属性类型尽量使用接口等
    4)针对扩展开放,针对改变关闭:项目中需求发生变化,应添加一个新的接口或类,而不要去修改源码
    总的来说,接口和抽象类是实现堕胎的2种重要方式,是面向对象设计的基础

Java面向对象 第5节 抽象类和接口的更多相关文章

  1. Java面向对象进阶篇(抽象类和接口)

    一.抽象类 在某些情况下,父类知道其子类应该包含哪些方法,但是无法确定这些子类如何实现这些方法.这种有方法签名但是没有具体实现细节的方法就是抽象方法.有抽象方法的类只能被定义成抽象类,抽象方法和抽象类 ...

  2. java面向对象基础(四):抽象类和接口

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  3. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

  4. Java第五次作业--面向对象高级特性(抽象类和接口)

    一.学习要点 认真看书并查阅相关资料,掌握以下内容: 掌握抽象类的设计 掌握接口的设计 理解简单工厂设计模式 理解抽象类和接口的区别 掌握包装类的应用 掌握对象的比较方法和比较器的使用 学习使用日期操 ...

  5. 牛客网Java刷题知识点之抽象类与接口

    不多说,直接上干货! 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于它们的存在才赋予java强大的面向对象的能力. ...

  6. 夯实Java基础(十)——抽象类和接口

    转载自:http://cmsblogs.com/ 该博主的网站上干货非常!非常!非常多(说三遍),强烈推荐大家前去学习. 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法 抽象类与接口是 ...

  7. Java基础系列4:抽象类与接口的前世今生

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 1.抽象类: 当编写 ...

  8. Java入门(一)——类、抽象类和接口

    Java是一门面向对象语言,可以看出"对象"在Java有着举足轻重的位置.那么,"对象"从何而来呢?那必须是丈母娘造出来的,下面我们就先来说说这个丈母娘--类. ...

  9. Java编程思想学习(七) 抽象类和接口

    1.抽象类和抽象方法 抽象方法:不完整的,仅有声明而没有方法体. abstract void f(); 抽象类:包含抽象方法的类.(若一个类包含一个或多个抽象方法,则该类必须限定为抽象的.) 1.用抽 ...

随机推荐

  1. [Angular] 'providedIn' for service

    There is now a new, recommended, way to register a provider, directly inside the @Injectable() decor ...

  2. CentOS安装glibc异常Protected multilib versions

    安装失败 在执行yum install glibc.i686 libstdc++.i686 libcurl.i686安装命令时出现Protected multilib versions 解决方案 在命 ...

  3. selenium java ,执行js改变页面

    1.面对页面一些页面上的限制而导致某些选择按钮无法选中的问题 很多时候由于页面上的一些限制会导致我们无法无法正常用webdriver来实现我们手动的正常操作,这时候我们可以通过执行js来适当的改变页面 ...

  4. ZCRM_AU_MAIL

    FUNCTION ZCRM_AU_MAIL. *"---------------------------------------------------------------------- ...

  5. 如何在linux下开启FTP服务

    如何在linux下开启FTP服务 1. 首先服务器要安装ftp软件,查看是否已经安装ftp软件下:   #which vsftpd   如果看到有vsftpd的目录说明服务器已经安装了ftp软件 2. ...

  6. REACT map dictionary

    Object.entries(obj).map(([key, value]) => ( console.log(key); console.log(value); ))

  7. 微信小程序城市定位(百度地图API)

    概述 微信小程序提供一些API(地址)用于获取当前用户的地理位置等信息,但无论是wx.getLocation,还是wx.chooseLocation均没有单独的字段表示国家与城市信息,仅有经纬度信息. ...

  8. vue教程自学笔记(一)

    一.介绍 1.指令 指令带有前缀v-,以表示它们是Vue提供的特殊特性.eg:v-bind,v-if,v-for,v-on,v-model(实现表单输入和应用状态之间的双线绑定) v-bind跟v-o ...

  9. 多进程—进程同步控制,IPC

    multiprocessing包—Process模块开启多进程的两种方式,Process的方法,守护进程 进程同步控制—multiprocessing.Lock  multiprocessing.Se ...

  10. CCF关于NOIP竞赛程序提交的管理规则

    在NOIP复赛中,NOI各省组织单位必须严格遵循CCF<关于NOIP数据提交格式的说明>的规范在竞赛结束后规定时间内向CCF提交本赛区所有参赛选手的程序. 为竞赛的公平以及赛后按时完成竞赛 ...