一、抽象类和抽象方法

  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. image magick 批量转换文件

    一个事例: You can set the output file name via -set + some percent escapes (in this case you need the di ...

  2. [Spring MVC] 取控制器返回的ModelAndView/Map/Model/Request的对象

    ${key }页面可取, <input value="${key}"> 或者<%=request.getParameter("key")%&g ...

  3. fastDfs V5.02 升级到 V5.08版本后,启动报错:symbol lookup error: /usr/bin/fdfs_trackerd: undefined symbol: g_current_time

    /libfastcommon-1.0.36 # ./make.sh cc -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -g -O3 -c -o hash.o ...

  4. Python自学:第二章 Python之禅

    >>print import <Python之禅>,提姆·彼得斯著 美胜于丑. 显式优于隐式. 简单胜于复杂. 复杂总比复杂好. 平的比嵌套的好. 稀疏胜于稠密. 可读性计数. ...

  5. 虚拟环境之virtualenvwrapper

    原来的virtualenv工具使用特别麻烦,主要体现在以下几点 1 创建虚拟环境的命令太长,太难记 2 管理特别麻烦 3 进入虚拟环境需要找到这个虚拟环境的存放目录才行,如果没有统一的存放目录,很难找 ...

  6. windows10安装MongoDB服务启动不了 😀✅已解决!

    WIndows的服务中,有一个服务需要以NT  AUTHORITY\NetworkService用户启动,但怎么也启动不起来,使用本地系统帐户启动没有任何问题,但是换成NetworkService就启 ...

  7. hello1

    1:选择hello1文件夹并单击“打开项目”.展开“Web页”节点,然后双击该index.xhtml文件以在编辑器中查看它. 该index.xhtml文件是Facelets应用程序的默认登录页面.在典 ...

  8. java中double和float精度丢失问题及解决方法

    在讨论两位double数0.2和0.3相加时,毫无疑问他们相加的结果是0.5.但是问题总是如此吗? 下面我们让下面两个doubles数相加,然后看看输出结果: @Test public void te ...

  9. golang并发(1)介绍

    概述 简而言之,所谓并发编程是指在一台处理器上“同时”处理多个任务. 随着硬件的发展,并发程序变得越来越重要.Web服务器会一次处理成千上万的请求.平板电脑和手机app在渲染用户画面同时还会后台执行各 ...

  10. 如何seo(搜索引擎优化)

    Seo是指遵循搜索引擎的搜索原则,对网站结构.网页文字语言和站点间互动外交等进行合理规划部署,以改善网站在搜索引擎的搜索表现,从而增加客户发现并访问网站的可能性的一个过程.