面向对象的三大特性

人盡茶涼 提交于 2020-03-01 06:00:22

学习 Java 的小伙伴都知道,Java 是面向对象的,谈起面向对象,当然离不开面向对象的三大特性:封装、继承、多态

封装

很好理解,比如我们平时去餐馆吃饭的时候,我们是看不到厨师的后台操作的,点完饭后,厨师根据我们的需求,将菜肴做好,但是我们是看不到做饭的过程的,这就是封装,把厨师做饭的过程封装起来,不对外显现,在 Java 中,我们也是这样,有时候不需要向用户展现某一部分我们是如何实现的,就可以把这部分封装起来,这样,类的调用者也不需要具体了解某个实现过程,减轻了类的调用者的负担,而实现封装,我们就可以用到之前提到过的 private 关键字

继承

现实生活中,我们经常听到儿子继承父亲的财产,对应到 Java 中也是一样的,子类(派生类)继承父类(基类、超类),子类拥有父类的属性和父类的方法,和财产继承一样,而继承我们是有语法的,使用到了 extends 关键字

class 子类 extends 父类{}

extends 关键字

  • Java中使用extends关键字实现类的继承机制
  • 通过继承子类自动拥有了基类(superclass)的所有成员(成员变量和成员方法)
  • Java只支持单继承
  • 一个子类只能有一个基类,一个基类可以派生出多个子类

继承有以下需要注意的:

  • 在 Java 中,继承是通过 extends 关键字来实现的,不可以使用 protected 和 private 修饰符
  • Java 中只支持单继承,即每个类只能有一个父类
  • 在 Java 中,所有的类都直接或间接的继承了 Object 类,Object 类是所有类的祖先
  • 如果存在多级继承,在创建一个子类对象时,会一直执行到父类为 Object 的无参构造方法
  • 如果子类的构造方法中没有通过 super 显示调用父类的有参构造方法,也没有通过 this 显示调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法
  • 如果子类的构造方法中通过 super 显示调用父类的有参构造方法,那将执行父类相应构造方法,不再执行父类无参构造方法
  • 关于调用构造方法大家可以参照之前介绍 super 关键字的代码

多态

多态,简单理解,不同类的对象对同意消息做出的不同响应,比如上课铃声响了,上体育课的同学就跑到操场站好,上文化课的同学坐在教室等待老师的到来

class Shape{
    public void draw(){
        System.out.println("我什么都不干");
    }
}
class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("○");
    }
}
class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("□");
    }
}
class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("♣");
    }
}
public class Practice {
    public static void main(String[] args) {
        Shape shape1 = new Flower();
        Shape shape2 = new Cycle();
        Shape shape3 = new Rect();
        Shape shape4 = new Shape();
        shape1.draw();
        shape2.draw();
        shape3.draw();
        shape4.draw();
    }
}
//执行结果
♣
○
□
我什么都不干

从上述代码我们可以看到 shape1 ,shape2 ,shape3 ,shape4,这四个引用的类型都是 Shape ,但是运行结果是不同的,这就是多态,那为什么是 Shape 类型的引用,结果却是调用了各个子类的方法,因为在编译阶段我们只看到 shape1 ,shape2 ,shape3 ,shape4 是 Shape 类型的,而 Shape 类是有 draw 方法的,所以编译通过,在运行时,才会真正调用各个实例对象的方法

看看下面的代码

class Shape{
    public void draw(){
        System.out.println("我什么都不干");
    }
}
class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("○");
    }
    public void print(){
        System.out.println("我是 Shape 的子类 Cycle");
    }
}

public class Practice1 {
    public static void main(String[] args) {
        Shape shape2 = new Cycle();
        Shape shape4 = new Shape();
        shape2.draw();
        shape2.print();
        shape4.draw();
    }
}
//编译错误

编译阶段, shape2 是属于 Shape 类型的,而 Shape 类没有 print 方法,即使我们知道在运行阶段应该调用的是 Cycle 的 print 方法,但是编译阶段是不知道的,所以就出现了错误

很明显可以看到多态存在的条件:

  • 有继承的关系
  • 子类重写父类方法
  • 父类引用指向子类对象

多态是建立在继承的基础上的

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!