首页 > 学院 > 开发设计 > 正文

Java从零开始学十八(抽象类和接口)

2019-11-14 23:02:38
字体:
来源:转载
供稿:网友
java从零开始学十八(抽象类和接口)一、什么是抽象类和接口

抽象类、接口与类是一个层次的概念,是java中极其重要的概念。

抽象类是从多个类中抽象出来的公共模板,提供子类均具有的功能。

接口是从多个类中抽象出来的规范,体现的是规范和实现分离的原则,同时也有效的解决了java单重继承的缺陷

二、抽象类2.1、抽象类与普通类的区别
  • 抽象类的class前面有abstract关键字,而普通类没有
/* * 抽象类 */public abstract class Person1 {}/* * 普通类 */public class Person {}
  • 抽象类中可以有抽象方法和普通方法,而普通类中只能有普通方法
  • 普通类可以实例化使用new,而抽象类不能实例化
2.2、抽象方法与普通方法区别
  • 抽象方法的前面有abstract关键字,而普通方法没有
  • 抽象方法没有方法体,而普通方法有方法体
    /*     * 抽象方法     */    public abstract void show();    //没有方法体/*     * 普通方法     */    public  void show(){        System.out.PRintln("这是个普通方法");    }   /*    * 普通类中不能有抽象方法    */
2.3、完整对比2个类
package com.pb.demo3;/* * 普通类 */public class Person {    private String name;  //名称    private int age ;  //年龄          /*     * 普通方法     */    public  void show(){        System.out.println("这是个普通方法");    }   /*    * 普通类中不能有抽象方法    */            //setter/getter方法    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }        }
package com.pb.demo3;/* * 抽象类 */public abstract class Person1 {    private String name;  //名称    private int age ;  //年龄    /*     * 抽象方法     */    public abstract void show();    //没有方法体            //抽象类中可以有普通方法    public void printSelf(){        System.out.println("这是个抽象类中的普通方法");            }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    }
2.4、如果抽象类被继承
  • 如果子类不是抽象类,则必须重写父类抽象类的全部抽象方法。(普通方法选择重写或者不写)
package com.pb.demo3;/* * 学生类继承Person1抽象类 */public class Student extends Person1 {        //继承时,会强制要求重写父类的抽象方法    @Override    public void show() {        System.out.println("重写父类的抽象方法");    }}
2.5 、一些注意事项
  • abstract不能与final关键字一起使用
  • private 关键字不能修饰抽象方法
  • abstract修饰的抽象方法没有方法体
2.6、图像对比

三、接口3.1、接口定义

接口使用interface关键字来定义

简单的说,接口是一个不能实例化,且只能拥有抽象方法的类型

public interface 接口名称{抽象方法}
public interface Person {}
package com.pb.demo4;public interface Person {        /*     * 定义2个抽象方法     */    public void run();        public  void say();}
3.2.为什么接口中的抽象方法不用使用abstract关键字?

因为接口中只能有抽象方法,所以不必专门使用abstract关键字来修饰,当然也可以加上不过完全没有必要

3.3、接口的抽象方法

接口的抽象方法只能由public来修饰

四、使用抽象类和接口4.1、抽象类使用继承来实现
/* * 抽象类 */public abstract class Person {        /*     * 普通方法     */    public void run(){        System.out.println("抽象类的普通方法! 走一走");    }        /*     * 抽象方法     */    public abstract void say();}
/* * 继承抽象类 */public class Student  extends Person{    @Override    public void say() {        System.out.println("实现父类的抽象方法!说一说");            }}
public class Test {    public static void main(String[] args) {        //声明子类对象        Student stu=new Student();        //调用子类重写的方法        stu.say();        //调用父类的普通方法        stu.run();    }}

结果:

实现父类的抽象方法!说一说抽象类的普通方法! 走一走
4.2、接口的使用

使用implements来实现接口,解决java中单继承的关系,接口可以是多个

package com.pb.demo4;public interface Person {        /*     * 定义2个抽象方法     */    public void run();        public  void say();}
package com.pb.demo4;/* * 实现接口Person */public class PersonImp implements Person {    /*     * 必须重写接口的全部抽象方法     */    @Override    public void run() {        System.out.println("实现接口的走一走抽象方法");    }    @Override    public void say() {        System.out.println("实现接口的说一说抽象方法");    }}
package com.pb.demo4;public class Test {    public static void main(String[] args) {        //声明对象        PersonImp p=new PersonImp();        //调用实现的方法        p.run();        p.say();    }}

结果:

实现接口的走一走抽象方法实现接口的说一说抽象方法
4.3 、对比实现

五、抽象类和接口的简单区别5.1、区别
  • 抽象类使用abstract声明,接口使用interface声明
  • 抽象类可以有抽象方法也可以有普通方法,接口只能有抽象方法
  • 实现方式不同:抽象类使用继承extends来实现,接口使用implements来实现
5.2、相同点
  • 抽象类和接口都不能实例化
5.3、图形对比

5.4、使用规则
  • 抽象类和接口都不能实例化
  • 抽象类与接口分别被继承与实现的场合,其子类必须实现其中的抽象方法
  • 抽象类中的抽象方法访问修饰符不能为private,接口中的抽象方法访问修饰符必须为public

六、简单实现抽象类
package com.pb.demo5;/* * 鸟类抽象类 */public abstract class Bird {    /*     * 飞的普通方法     */    public void fly(){        System.out.println("弹射飞!");    }    /*     * 攻击抽象方法     */    public abstract void attack();    }
package com.pb.demo5;/* * 火箭鸟 */public class RocketBird extends Bird {   /*    * 重写攻击方法    */    @Override    public void attack() {        System.out.println("火箭鸟攻击方式:加速冲撞!");    } }
package com.pb.demo5;/* * 分裂鸟 */public class SplittBird extends Bird {   /*    * 重写攻击方法    */    @Override    public void attack() {        System.out.println("分裂鸟攻击方式:分裂攻击!");    }   }
package com.pb.demo5;public class Test {    public static void main(String[] args) {                /*         * 多态的应用         */        //创建鸟类对象,实例化为分裂鸟对象        Bird splitbird=new SplittBird();        //创建鸟类对象,实例化为火箭鸟对象        Bird rocketbird=new RocketBird();        //分别调用鸟类的普通飞的方法        //分别调用子类重写后的叫方法        //分别调用子类重写后的攻击方法        splitbird.fly();         splitbird.attack();                rocketbird.fly();           rocketbird.attack();            }}

结果:

弹射飞!分裂鸟攻击方式:分裂攻击!弹射飞!火箭鸟攻击方式:加速冲撞!

从上例子中可以看出:子类相同的方法,如:飞的方法 可以放在父类的抽象类中使用普通方法实现,实现代码的重用,而不同的部分,使用抽象方法,子类来实现自己的方法,简单来讲:抽象类就是抽取公共的部分在抽象来中来实现

如:完全没有相同的方法,但都有这此方法,该怎么实现呢?这时候就需要接口大神出场

七、简单接口实现

还是以上例为例,比如,连有叫的方法,但每种 鸟的叫声都不一样呢?有的会叫,有的不会叫,

package com.pb.demo5;/* * 叫的接口 */public interface Shout {    /*     * 叫的方法     */  public void shout();}package com.pb.demo5;public class AoShoutImpl implements Shout {    @Override    public void shout() {        System.out.println("嗷嗷叫!");    }}package com.pb.demo5;public class ZhaShoutImpl implements Shout {    @Override    public void shout() {        System.out.println("喳喳叫!");    }}package com.pb.demo5;public class NoCanShoutImpl implements Shout {    @Override    public void shout() {        System.out.println("不会叫!");    }}
package com.pb.demo5;/* * 鸟类抽象类 */public abstract class Bird {    Shout shout;    /*     * 构造方法     */    public Bird(Shout shout) {        super();        this.shout = shout;    }/* * 叫的普通方法 */    public void shout(){        //调用自身叫的方法        shout.shout();    }        /*     * 飞的普通方法     */    public void fly(){        System.out.println("弹射飞!");    }    /*   * 抽象攻击方法   */    public abstract void attack();    }
package com.pb.demo5;/* * 炸弹鸟 */public class Bombbird extends Bird {            public Bombbird(Shout shout) {        super(shout);    }    @Override    public void attack() {    System.out.println("炸弹鸟攻击方式:炸弹攻击");    }    @Override    public void shout() {        System.out.println("炸弹鸟:喳喳叫!");    }}package com.pb.demo5;/* * 胖子鸟 */public class Fatbird extends Bird {    public Fatbird(Shout shout) {        super(shout);    }    @Override    public void attack() {    System.out.println("胖子鸟攻击方式:下蛋攻击");    }    @Override    public void shout() {        System.out.println("胖子鸟:不会叫!");    }}package com.pb.demo5;/* * 红色鸟 */public class Redbird extends Bird  {    public Redbird(Shout shout) {        super(shout);            }    @Override    public void attack() {    System.out.println("红色鸟攻击方式:普通攻击");    }    @Override    public void shout() {        System.out.println("红色鸟:喳喳叫!");    }}package com.pb.demo5;import com.pb.demo5.Bird;/* * 火箭鸟 */public class RocketBird extends Bird  {   public RocketBird(Shout shout) {        super(shout);            }    /*    * 重写攻击方法    */    @Override    public void attack() {        System.out.println("火箭鸟攻击方式:加速冲撞!");    }       /*     * 重写叫的方法     */    @Override    public void shout() {        System.out.println("火箭鸟:嗷嗷叫!");            }  }package com.pb.demo5;/* * 分裂鸟 */public class SplittBird extends Bird {   public SplittBird(Shout shout) {        super(shout);            }    /*    * 重写攻击方法    */    @Override    public void attack() {        System.out.println("分裂鸟攻击方式:分裂攻击!");    }    /*     * 重写叫的方法     */    @Override    public void shout() {        System.out.println("分裂鸟:嗷嗷叫!");            }}
package com.pb.demo5;import com.pb.demo5.Bird;public class Test {    public static void main(String[] args) {        /*         * 创建接口对象         */        Shout  aoshout=new AoShoutImpl();        Shout zhashout=new ZhaShoutImpl();        Shout noshout=new NoCanShoutImpl();        /*         * 多态的应用         */        //创建鸟类对象,实例化为分裂鸟对象        Bird splitbird=new SplittBird(aoshout);        Bird rocketbird=new RocketBird(aoshout);        Bird bomb=new Bombbird(zhashout);        Bird redbird=new Redbird(zhashout);        Bird fatbird=new Fatbird(noshout);        splitbird.fly();        splitbird.attack();        splitbird.shout();            rocketbird.fly();        rocketbird.shout();        rocketbird.attack();                bomb.fly();        bomb.shout();        bomb.attack();              redbird.fly();        redbird.shout();        redbird.attack();                fatbird.fly();        fatbird.shout();        fatbird.attack();                    }}

结果:

弹射飞!分裂鸟攻击方式:分裂攻击!分裂鸟:嗷嗷叫!弹射飞!火箭鸟:嗷嗷叫!火箭鸟攻击方式:加速冲撞!弹射飞!炸弹鸟:喳喳叫!炸弹鸟攻击方式:炸弹攻击弹射飞!红色鸟:喳喳叫!红色鸟攻击方式:普通攻击弹射飞!胖子鸟:不会叫!胖子鸟攻击方式:下蛋攻击

由上可以看出:抽象类方便代码复用,接口方便代码维护


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表