面向对象————继承、封装、多态、抽象类

一、继承

1.定义:是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。 

Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

2.语法:

public class A{}
public class B extends A{ } // 基于A已有成分的基础上扩展出B这个子类

(个人理解:就是一个类加上extends+被继承的类名,它变成了继承类能访问被继承类的非私有成员,意义就是减少代码冗余。)

===注意===:

Java是单继承的,一个类只能继承一个直接父类。

3.案例:

需求:请定义以下类:

1.Son1类

属性:姓名,年龄

行为:上学、吃饭

2.Son2类

属性:姓名,年龄

行为:考研、吃饭

思路:为防止代码冗余我们采用继承方式来定义以下类,即将三个类的公共部分写于Father类中,其他特有的部分则在自己类里书写,再使用测试类(Test)来测试

公共类:

Son1类:

Son2类:

 

 测试类(Test):

结果:

(当子类中有与父类重名的属性:直接书写属性则是局部变量,this为本类的成员变量,super为专门访问父类空间的关键字)。

二、封装

1.定义:隐藏实现细节,仅对外暴露公共的访问方式。

将代码抽取到方法中,这是对代码的一种封装。

将属性抽取到类中,这是对数据的封装。

2.封装的优点:

提高了代码的安全性

提高了代码的复用性

3.封装的常见提现:

私有成员变量,提供set与get方法

将代码抽取到方法中,这是对代码的一种封装

将属性抽取到类当中,这是对数据的一种封装

(个人见解:封装就好比一个插座,我们不知道里面的构成,只知道外面的模式,知道怎么使用。)

 三、多态

1.定义:在java里,多态是同一个行为具有不同表现形式或形态的能力,即对象多种表现形式的体现,就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

比如方法的重载,多态也可以体现在面向对象中,一个对象可以使用多种类型来表示

2.案例:

//定义Animal类及其子类Dog,Cat测试案例。
class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}

/**
 * 1.需要有继承或者实现
 * 2.需要有方法的重写【意义体现】
 * 3.父类型引用指向子类对象
 *
 * 常见多态代码体现在三个地方:
 * 1. 直接定义变量:父类型变量接收子类对象
 * 2. 方法参数:父类型的形参接收子类型的实参对象
 * 3. 返回值:父类型的返回值类型接收子类型的返回值对象
 */
public class Demo01 {
    public static void main(String[] args) {
        Cat c = new Cat();//没有体现多态
        //多态体现
        Animal a1 = new Cat();//父类型变量(引用)接收子类对象
        Animal a2 = new Dog();
        //相同方法的执行,有不同的结果
        a1.eat();
        a2.eat();

        //==============
        Dog d = new Dog();
        show(d); // Animal a = d;  也是体现了多态

    }


    public static void show(Animal a) {
        a.eat();
    }

    public static Animal getAniamal() {
        return new Cat();
    }

}
class Animal{
    public void eat() {
        System.out.println("动物吃东东~~");
    }
}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫儿吃鱼~~");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗啃骨头~~~");
    }
}

 四、抽象类

一个被abstract关键字修饰的类就是抽象类,抽象类不一定有抽象方法,但是有抽象方法的类一定是抽象类,抽象类一般作为模板使用。

使用abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。

定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表);

代码举例:

public abstract void run();

如果一个类包含抽象方法,那么该类必须是抽象类。注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。

定义格式:

public abstract class 类名字 { 
  
}

代码举例:

定义Animal抽象类,含有抽象方法run方法。

//写抽象类Animal并含有抽象方法run
abstract class Animal {
    int age;
​
    public abstract void run();
​
    public void eat() {
    }
}

继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。

==抽象类注意点==

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  2. 抽象类中,可以有构造器,是供子类创建对象时,初始化父类成员使用的。

    理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则子类也必须定义成抽象类,编译无法通过而报错。

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

  5. 抽象类存在的意义是为了被子类继承,抽象类体现的是模板思想。

    理解:抽象类中已经实现的是模板中确定的成员,抽象类不确定如何实现的定义成抽象方法,交给具体的子类去实现。

抽象类存在的意义是为了被子类继承,否则抽象类将毫无意义,抽象类体现的是模板思想,模板是通用的东西抽象类中已经是具体的实现(抽象类中可以有成员变量和实现方法),而模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求,这是典型的模板思想。

模板模式

我们现在使用抽象类设计一个模板模式的应用,例如在小学的时候,我们经常写作文,通常都是有模板可以套用的。

假如我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同,新司机:开门,点火,双手紧握方向盘,刹车,熄火老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火。我们可以将固定流程写到父类中,不同的地方就定义成抽象方法,让不同的子类去重写,代码如下:

// 司机开车的模板类
public abstract class Driver {
    public  void go() { //模板方法:具体定义了固定的流程
        System.out.println("开门");
        System.out.println("点火");
        // 开车姿势不确定?定义为抽象方法
        ziShi();
        System.out.println("刹车");
        System.out.println("熄火");
    }
​
    public abstract void ziShi();
}

现在定义两个使用模板的司机:

public class NewDriver extends Driver {
​
    @Override
    public void ziShi() {
        System.out.println("新司机双手紧握方向盘");
    }
}
​
public class OldDriver extends Driver {
    @Override
    public void ziShi() {
        System.out.println("老司机右手握方向盘左手抽烟...");
    }
}

编写测试类

public class Demo02 {
    public static void main(String[] args) {
        NewDriver nd = new NewDriver();
        nd.go();
​
        OldDriver od = new OldDriver();
        od.go();
    }
}

运行效果:

 

可以看出,模板模式的优势是,模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!非常的强大!

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值