栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

小比特笔记--java抽象类abstract class

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

小比特笔记--java抽象类abstract class

目录

复习重写

方法重写的类型的返回值必须严格相同:

抽象类

接口

代码:鼠标和键盘插入

兔子狗鸭子

关于接口的命名规范

Object类


目录

复习重写

方法重写的类型的返回值必须严格相同:

抽象类

接口

代码:鼠标和键盘插入

兔子狗鸭子


复习重写

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
    private void test(){
        // The test method  is  private,Subclasses don't even know test exists.
        //so ,unable to rewrite.
        //private method only visible inside the current class.
        System.out.println("Person test method");
    }
}

class Student extends Person{//子类 subclasses
    public void test(){
        System.out.println("test method of student class ");
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}
package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     void test(){// After the elimination of private.
        System.out.println("Person test method");
    }
}

class Student extends Person{//子类 subclasses
     //The subclass is overridden 此时子类被重写了
    public void test(){
        System.out.println("test method of student class ");
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

code output  "test method of student class "!!

子类和父类有不同的标记符号:

子类向上,父类向下;

方法重写的类型的返回值必须严格相同:

毫无相关的 两种类型不能作为方法重写的返回值,比如受父类中的是int而子类中的是boolean,这就不可以返回,不算方法重写,会报成不兼容。

这时子类使用student作为返回值,父类使用Person作为返回值是可以的,因为这个student本来就是Person, student is a person。

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     Person test(){
        System.out.println("Person test method");
        return new Person();
    }
}

class Student extends Person{//子类 subclasses
    public  Student test(){
        System.out.println("test method of student class ");
        return  new Student();
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

如果反过来父类中是返回Student,子类中返回person 呢?

会报错:“attempting to use incompatible return type”           尝试使用不兼容的类型。

原因这时是向下转型,而不是向上转型,person is not a  student,

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     Student test(){
        System.out.println("Person test method");
        return new Student();
    }
}

class Student extends Person{//子类 subclasses
    public  Person test(){
        System.out.println("test method of student class ");
        return  new Person();
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

一般情况下,重写方法的返回值类型不一定和父类相同,但是建议写成相同。

抽象类

抽象类只是比普通类多了一些抽象的方法,可以是0个或者n个。

抽象方法所在的类必须是抽象类,子类若继承了抽象类,必须复习所有的抽象方法(但是子类必须是不同类)。

抽象方法是使用abstract关键字声明,没有函数实现的方法。

java中定义抽象类或者抽象方法使用abstract关键字;

抽象方法的实现要在子类中去实现。

1只要使用抽象类必须用abstract声明为抽象类

此时的print只有方法的声明,没有方法体。所谓的方法体就是{}

没有方法体的方法不一定就是抽象方法。

本地方法native表示本地的,这个方法不是抽象方法,具体实现由C++写好的方法完成。

2若一个类使用abstract声明为抽象类,无法直接通过该类实例化对象,哪怕该类中一个抽象方法都没有。当一个类是抽象类,不管有没有抽象方法,这个类本身就是一个抽象的概念,没法具体到某个特定实例。

抽象类不能自己实例化对象,只能通过子类向上转型转为抽象父类的引用。

Sharp sharp =new Sharp();  // false

人类是一个抽象的概念

Person person= new Person(); // false

Person  person=new China(); //   true

        

3子类继承了抽象类就必须强制要求重写所有的抽象方法(子类是个普通类),一个子类只能extends一个抽象类

类“C”必须声明为抽象,或者实现抽象方法“printB()”

如果B中没有重写A,那么普通类C要实现两次
package Sharp;

public class code1 {
    abstract class A{
        abstract void printA();
    }
    //B 是一个抽象类,可以选择性的重写父类中的抽象方法
    abstract class B extends A{
        //这个pintA  B没有重写
        abstract void printB();
    }
    //C是普通类,必须重写B中的所有抽象方法
    class C extends B{
        @Override
        void printA() {
        }
        @Override
        void printB() {
        }
    }
}

如果B重写了A
package Sharp;

public class code1 {
    abstract class A{
        abstract void printA();
    }
    //B 是一个抽象类,可以选择性的重写父类中的抽象方法
    abstract class B extends A{
        abstract void printB();
        //如果我在B中重写了A,C就不需要重写两次了
        @Override
        void printA() {
        }
    }
    //C是普通类,必须重写B中的所有抽象方法
    class C extends B{

        @Override
        void printB() {
        }
    }}

4.抽象类虽然没法直接实例化对象,但是可以存在构造方法,子类在实例化对象的时候仍遵从继承的原则。先调用父类的构造方法,而后调用子类的构造方法。
package Sharp;

abstract class BaseTest{
    public BaseTest(){
        this.print();
    }
abstract void print();
}
public class Fun extends  BaseTest{
    private  int num=10;

    @Override
    void print() {
        System.out.println("num="+num);
    }

    public static void main(String[] args) {
        new  Fun();
    }
}

先调用父类,然后this.print()调用被子类重写的方法,此时num==0;

 到底啥时候会用到抽象类,稍微复杂一点,先阶段主要掌握接口类的定义与使用。

若一个需求既可以使用抽象类也可以使用接口,优先使用接口 ,因为抽象类依然是单继承局限。

接口

抽象类虽然没法直接实例化对象,但是子类仍然满足  is  a  原则,子类和抽象父类之间仍然是一个强的继承树关系,Person 对于China 和Sharp 对于Cycle, China 只能继承Person,  Cycle 只能继承 Sharp,而接口是一个混合的概念,他不是一个垂直的方向。接口的使用一般表示两种,

1.接口表示具备某种能力或者行为,子类在实现接口时不是 is  a 关系,而是具备这种行为能力。

比如 游泳 ,Person  满足游泳接口,  Dog也能满足游泳的接口,他是一个混合的实现,Duck 也能满足游泳接口,此时游泳接口就是一个表示游泳能力或者行为。

2.接口表示一种规范,比如“USB”接口,“5G标准”。

接口中只有全局常量和抽象方法,更加存粹的抽象概念,其他东西都没有。

接口使用关键字-interface声明接口,子类使用implement实现接口;

1.USB接口

 

 USB接口表示一种规范,那么显示生活中哪些类使我们接口的子类,鼠标,键盘这种外设都是。

子类使用implements实现接口,必须重写所有的抽象方法。

 

 电脑这个类不属于USB接口的子类,所有带USB线插入到电脑的设备都应该满足USB规范,电脑叫做USB规范的使用者。

 其实鼠标和键盘我们都需要各有一个接口,所以这个例子不太好。

代码:鼠标和键盘插入
package usb;


public interface USB {
    // 插入
    public abstract  void plugIn();
    //工作
    public abstract void work();
}
package usb;

public class Mouse implements USB{

    @Override
    public void plugIn() {
        System.out.println("安装鼠标驱动");
    }

    @Override
    public void work() {
        System.out.println("鼠标开始工作");
    }
}
package usb;

public class KeyBoard implements USB{

    @Override
    public void plugIn() {
        System.out.println("安装键盘驱动中");
    }

    @Override
    public void work() {
        System.out.println("键盘正常工作");
    }
}
package usb;

public class Computer {
    public static void main(String[] args) {
        Computer computer=new Computer();
        Mouse mouse =new Mouse();
        //调用fun方法把mouse传入,插入一个鼠标
        computer.fun(mouse);
        KeyBoard keyBoard=new KeyBoard();
        computer.fun(keyBoard);
    }
       public void fun(USB usb){
        usb.plugIn();
        usb.work();
    }
}

安装鼠标驱动
鼠标开始工作
安装键盘驱动中
键盘正常工作

假如现在这可接口要插入Camera,电脑的fun方法不用变,只要写一个子类,然后创建对象,引用传入就行了,这也是多态。

开闭原则,所有设计模式的核心思想:程序应该的拓展开放,对修改关闭。方便扩展,不能影响已经写好的程序。

 

  

接口表现能力!

接口允许多实现,一个类可以具备多种能力        ,同时实现多父接口,若实现多个父接口,子类普通类,需要复写所有抽象方法。 

一个类既需要继承一个父类又需要实现多个接口时:

类名 extends 父类 implements 接口1,接口2...{}

兔子狗鸭子
package animal;

public interface ISWim {
    public abstract void swim();
}

package animal;


public interface IRun {
    public abstract void run();
}

package animal;


public interface IFly {
    public abstract void fly();
}

package animal;
//兔子只会跑不会游泳
public class Rabbit implements IRun{
    @Override
    public void run() {
        System.out.println("兔子再跑~~");
    }
}

package animal;
//Dog会跑也会游泳
public class Dog implements IRun,ISWim{
    @Override
    public void run() {
        System.out.println("狗在跑~~~~");
    }

    @Override
    public void swim() {
        System.out.println("狗在游泳~~~~");
    }
}

package animal;
//鸭子会跑回游会飞
public class Duck implements IRun,IFly,ISWim {
    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }

    @Override
    public void run() {
        System.out.println("鸭子在跑");
    }

    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }
}

package animal;

public class Test {
    public static void main(String[] args) {
        //接口也不能直接实例化对象,需要向上转型

        IRun run = new Rabbit();
        IRun run1 = new Dog();
        IRun run2 = new Duck();
        ISWim swim = new Dog();
        ISWim swim1 = new Duck();
        IFly fly = new Duck();
        run.run();
        run1.run();
        run2.run();
        swim.swim();
        swim1.swim();
        fly.fly();
    }
}

兔子再跑~~
狗在跑~~~~
鸭子在跑
狗在游泳~~~~
鸭子在游泳
鸭子在飞

由于接口中只会有全局常量和抽象方法,因此接口中

public abstract=>抽象方法

static final=>常量

全都可以省略!!!

package animal;

public class Test {
    public static void main(String[] args) {
        //接口也不能直接实例化对象,需要向上转型

        IRun run = new Rabbit();
        IRun run1 = new Dog();
        IRun run2 = new Duck();
        ISWim swim = new Dog();
        ISWim swim1 = new Duck();
        IFly fly = new Duck();
        run.run();
        run1.run();
        run2.run();
        swim.swim();
        swim1.swim();
        fly.fly();
    }
}

兔子再跑~~
狗在跑~~~~
鸭子在跑
狗在游泳~~~~
鸭子在游泳
全局常量
鸭子在飞
 

在定义抽象方法时,abstract和final不能同时出现,抽象方法必须 重写,final修饰后无法重写。

在定义抽象类时,也不可以,抽象类必须有子类,final修饰没有子类。

关于接口的命名规范

命名接口使用         I  开头,IRun,ISwim
子类实现一个接口时

命名以相应的接口开头,以impl结尾,

eg:如果是IRun的子类,以IRunimpl结尾,这个命名不是强制要求。

如果子类实现多个父接口不需要使用此规范来命名比如Duck即会游泳有会跑又会飞就不需要使用固定的结尾

Object类

全名称: 包名.类名

java.lang.Object

1.Object类是java中所有类默认的父类,无需使用extends来定义,class声明的类都有一个父类,Object类。

因为object类是所有类的子类,使用Object引用来接收所有类型,参数最高统一化。

Object obj1=new Person();

Object obj2=new String();

Object obj3=new Dog();

都可以通过向上转型变成object,所有类型都可以,这叫参数的最高统一化。

假如说有一个参数实object类型的,void fun(Object obj){},说明他可以接受所有的类型。

2.Object是所有类的父类,那么子类可以继承父类的所有方法!

之所以System.out.prientln(任意的引用类型)-->默认都调用toString()方法,是因为Object类存在toString方法。

这就是为什么sout中传入什么类型的对象都能够打印的原因。

还有,方法能不能重写看的是前面的引用有没有这个属性,如果有就调用子类重写后的代码:

3.java中引用数据类型之间的相等比较使用equals方法!        不能使用“==”比较的是地址;

Object类存在equals方法!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873639.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号