菜鸟成长系列-面向对象的四大基础特性

2,351 阅读5分钟

按照之前的学习规划,开始进行第一部分的学习。那么今天就重新认识一下JAVA中的四大特性:抽象、封装、继承、多态

抽象

学习面向对象,抽象还是很重要的。面向对象最接近我们人类的思维,你的抽象能力就是你对万物万事总结和归纳的能力。关于抽象,就是从具体事物抽出、概括出它们共同的方面、本质属性与关系等,而将个别的、非本质的方面、属性与关系舍弃,这种思维过程,称为抽象。在JAVA中表现就是使用abstract来修饰类,被abstract修饰的类成为抽象类,一般是为了为子类提供一些共有的属性和行为,不同的子类根据自身的特性再进行具体的行为实现。

封装

封装是面向对象的重要原则,就是把对象的属性和行为(方法)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节;在java中,对于对象的内部属性一般用private来实现隐藏,并通过set和get方法对外提供访问接口。封装实际上是一种信息隐藏技术的实现方式。

  • 对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。
  • 对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。

例如:对于客观存在的人这个对象进行属性和行为抽象【此处仅仅是部分抽象】;使用private关键字来修饰人的属性,并通过对应的set和get方法对外界提供访问入口;在行为方面,通过public关键字来修饰,对外提供具体的行为描述。外界对象并不知道“人”这个对象在内部发生了什么,仅仅是通过提供的方法来获得具体的描述信息。

/**
 * 人
 * @author glmapper
 *
 */
public class Person {
    //姓名
    private String name;
    //年龄
    private int age;
    //性别
    private String sex;
    //身高
    private float high;
    //体重
    private float weight;
    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;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public float getHigh() {
        return high;
    }
    public void setHigh(float high) {
        this.high = high;
    }
    public float getWeight() {
        return weight;
    }
    public void setWeight(float weight) {
        this.weight = weight;
    }


    public void eat(){
        System.out.println("吃东西");
    }

    public void walk(){
        System.out.println("走路");
    }

    public void study(){
        System.out.println("学习");
    }
}

继承

继承是面向对象最显著的一个特性,是从已有的类中派生出新的类,我们把它称之为子类,子类继承父类的属性和行为,并能根据自己的需求扩展出新的属性和行为,提高了代码的可复用性。

  • 提高了代码的复用性。
  • 让类与类之间产生了关系,给第三个特征多态提供了前提。

Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(有的也称其为基类、超类),父类和子类的关系,是一种一般和特殊的关系;子类扩展父类,将可以获得父类的全部属性和方法。

男人是人的一种,男人的特征是有胡子,因此也有剪胡子的行为【有胡子和剪胡子并非依赖关系;一个是属性,一个是行为】;但是男人继承了人这个父类,因此,男人也具有例如姓名、性别、身高、体重等属性,同时也具有父类人具有的吃饭、走路和学习的行为。

/**
 * 男人
 * @author glmapper
 *
 */
public class Man extends Person{
    //胡子
    private String  goatee;

    public String getGoatee() {
        return goatee;
    }

    public void setGoatee(String goatee) {
        this.goatee = goatee;
    }

    public void shaved(){
        System.out.println("剪胡子");
    }
}

重写父类的方法:
大部分的时候,子类总是以父类为基础,额外添加新的属性和方法。但有一种情况例外:子类需要重写父类的方法。例如男人吃东西比较快,女人吃东西比较慢,因此对于eat方法来说,Man可以覆盖父类的eat方法,来描述Man本身的特点。

@Override
public void eat(){
    System.out.println("快速的吃东西");
}

当子父类中出现相同方法时,会先运行子类中的方法。
重写的特点:方法名一样,访问修饰符权限不小于父类,返回类型一致,参数列表一致。

多态

定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。从语言特点上来说,Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态(Polymorphism)。
封装和继承都是为Java语言的多态提供了支撑;多态存在的三个必要条件:

  • 要有继承;
  • 要有重写;
  • 父类引用指向子类对象。

具体的实现方式就是:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

下一篇在说类和接口的时候再用具体的例子来描述覆盖、重载。