Java面向对象之抽象类

一,为什么实用抽象类?

案例

1:定义Dog

  有颜色属性和叫的方法

2:定义Bird

  有颜色属性和叫的方法

3:定义其父类Animal

  1:抽取共性颜色属性和叫的方法

    1:颜色的属性可以使用默认初始化值。

    2:叫的方法在父类中如何定义?

      1:狗是旺旺

      2:鸟是叽叽喳喳

      3:可以将父类的方法定义为狗叫让鸟继承父类重写叫的方法

        1:鸟怎么确定是否要重写父类方法。

        2:不重写,编译和运行都没有问题,只是执行鸟叫的方法就会出现狗叫

      4:父类的方法很难确定。

 

class Animal {
    String color;

     void shout(){
         //如何定义呢?是旺旺还是叽叽喳喳?
     }
}

class Dog extends Animal {

    void shout() {
        System.out.println("旺旺");
    }

}

class Bird extends Animal {

    void shout() {
        System.out.println("叽叽喳喳");
    }
}

 

 

 

二,抽象类

1,定义:

当描述一个类的时候,如果不能确定功能函数如何定义,那么该类就可以定义为抽象类,功能函数应该描述为抽象函数。

2,抽象类的实现方法

  1,定义animal类

    1,定义叫的方法,无法确定方法体,不写方法体。

      public void shout();编译失败

    2,根据提示在shout的方法中加abstract修饰

       1,编译失败,有新的提示

    3,根据提示将类加入abstract修饰

      1,编译通过

abstract class Animal {
    String color;

    abstract void shout();
}

class Dog extends Animal {

    void shout() {
        System.out.println("旺旺");
    }

}

class Bird extends Animal {

    void shout() {
        System.out.println("叽叽喳喳");
    }
}

 

 

 

 

3,抽象类的特点

  1,有抽象函数的类,该类一定是抽象类。

  2,抽象类中不一定要有抽象函数。

  3,抽象类不能使用new创建对象

    因为创建对象,使用对象的功能,抽象类的方法,没有方法体。

    问1:抽象类不能创建对象,name抽象类中是否有构造函数?

    答:抽象类中一定有构造函数,主要为了初始化抽象类中的属性。通常由子类实现。

    问2:final和abstract是否可以同时修饰一个类?

    答:一定不能同时修饰

  4,抽象类主要为了提高代码的复用性,让子类继承类使用。

  5,编译器强制子类实现抽象类父类的为实现的方法。

    可以不实现,前提是子类的也要声明为抽象的。

4,抽象类的优点

  1,提高代码的复用性

    强制子类实现父类中没有实现的功能

  2,提高代码的扩展性,便于后期的代码维护

 

abstract class Animal {

    String name;

    // 抽象类可以有构造函数
    Animal() {

    }

    Animal(String name) {
        this.name = name;
    }

    abstract void shout();

}

class Dog extends Animal {
    Dog() {

    }

    Dog(String name) {
        super(name);
    }

    void shout() {
        System.out.println("旺旺");

    }
}

class Demo3 {

    public static void main(String[] args) {
        // 抽象类不能创建对象
        // Animal a=new Animal();
        Dog d = new Dog("旺财");

        System.out.println();
    }
}

 

 

三,抽象类练习

 

1:定义抽象类MyShape(图形)

 

  1:定义抽象方法获取图形的长度和面积

 

2:定义子类Rect继承父类MyShape   

 

  1:定义自身特有的长和宽(成员变量)  width height;

 

  2:实现父类未实现的函数。

 

3:定义子类 Circle实现父类MyShape

 

  1:定义自身特有的半径和圆周率(使用常量)

 

  2:实现父类为实现的方法。

 

 

/*
 }
 2:抽象练习 
 1:定义抽象类MyShape(图形)
 1:定义抽象方法获取图形的长度和面积
 2:定义子类Rect继承父类MyShape   
 1:定义自身特有的长和宽(成员变量)  width height;
 2:实现父类未实现的函数。
 3:定义子类 Circle实现父类MyShape
 1:定义自身特有的半径和圆周率(使用常量)
 2:实现父类为实现的方法。
 */
abstract class MyShape {

    abstract double getLen();

    abstract double getArea();

}

class Rect extends MyShape {
    double width;
    double height;

    Rect() {

    }

    Rect(double width, double height) {
        this.width = width;
        this.height = height;
    }

    double getLen() {
        return 2 * (width + height);
    }

    double getArea() {
        return width * height;
    }
}

class Circle extends MyShape {
    double r;
    public static final double PI = 3.14;

    Circle() {

    }

    Circle(double r) {
        this.r = r;
    }

    double getLen() {
        return 2 * PI * r;
    }

    double getArea() {
        return PI * r * r;
    }
}

class Demo4 {

    public static void main(String[] args) {
        Rect r = new Rect(5, 5);
        System.out.println(r.getLen());
        System.out.println(r.getArea());
        System.out.println();

        Circle c = new Circle(5);
        System.out.println(c.getLen());
        System.out.println(c.getArea());

    }
}

 

 

 

四,抽象类注意细节

抽象类可以没有抽象方法

抽象类可以继承普通类与抽象类

抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化。

抽象类一顶有构造方法。

abstract 与其他修饰符的关系:

  final与abstract 不能共存

    final:它的作用,修饰类代表不可以继承,修饰方法不可以重写。

    abstract 修饰类就是用来被继承的,修饰方法就是用例被重写的。

  static 修饰的方法可以用类名调用

    对于abstract 修饰的方法没有具体的方法实现,所有不能直接调用,

    也就是说不可以与static共存。

  private

    private修饰的只能在本类中使用。

    abstract 方法是用来被子类进行重写的。有矛盾,所以不能共存。

五,值的交换

5.1,基本数据类型交换

 

public class TestDemo {
    public static void main(String[] args) {
        int a = 4;
        int b = 6;
        System.out.println("交换前的值:"+"a = "+a+" b="+b);  // a=4,b=6
        change(a,b);
        System.out.println("交换后的值:"+"a = "+a+" b="+b);  // a=4,b=6
    }

    public static void change(int a,int b){
        int temp = a;
        a = b;
        b = temp;
    }
}

 

 

 

结果:发现交换值前后没有变量的的值发生变化

原因分析:主函数运行的时候会在栈内存中开辟属于自己的控件,当主函数调用change函数的时候,也会在栈内存中开辟属于自己的空间,并有自己的a,b变量。当change方法结束之后,change方法中的a,b变量也会同时消失。

 

 5.2 数组类型交换

 

 

 

 结果:交换值成功。

 

 

 5.3对象的值交换

 

 

 

 

 

 结果:交换值成功

 

 5.4 字符串的值交换

 

 交换值失败

 

posted @ 2021-08-07 15:31  勇敢面对difficult  阅读(95)  评论(0)    收藏  举报