面向对象编程(Object Oriented Programming,OOP)是当前最主流的编程范式之一,Java是一门纯面向对象的编程语言。我们常说C++是一门面向对象的编程语言,C++是C语言的一个超集,它在C语言的基础上突破性的添加了类的概念,增加了面向对象的特点。

首先,C++是一门非常强大的语言,它几乎可以做到其他编程语言所能做到的所有事情,但是由于其繁杂的语法等等原因导致C++的学习成本过高,在这样地背景下,Java逐渐取代并且成为了一门主流的编程语言。而理解面向对象,首先要理解基本的类与对象的概念。

一、类与对象

众所周知,类型是人类意识形态进化过程中重要的一环,分类思想最早有亚里斯多德提出。所谓分类,即将事物通过某些区别将具有相同特点的事物划分为一类,换句话说,类型,即是具有相同特点的事物。OOP面向对象的核心之一就是类,我们需要设计一个类(这里使用类型可能更好理解一些),用以概括具有相同特点的事物,而对象就是具体的某一个满足这些特点的东西。

我们列举一个example,水壶是一个类型,水壶有都有各自的颜色。设计一个水壶的类,那么红色的水壶就是这个类的一个对象。 笔者认为,面向对象思想借鉴了中最重要的一点就是借鉴了“类型”的概念。

我们在分析设计类的时候,总是思考该类的属性以及行为,来设计该类的成员变量和成员方法.并且通过“行为”的设计来模拟现实世界事物的关系。比如,Person有一个touch()方法。它的方法签名如下:

public void touch(LiftButton liftButton);

这个方法很好的模拟了“人按下电梯键”这个行为。通过使用这种方法以及Java简练的语法极大地简化了开发的难度。

值得一提的是,我们通常在对象后面加“.”用以访问对象的成员。如:

Person p = new Person();

p.age;

Example code:


class Person {
int age;
double height;
double weight;
public void touch(LiftButton liftButton) {
//...
}
}

二、深入OOP---继承和多态:

在理解的基本的类与对象之后,先不需要急着明白继承是什么,接着按照“分类”理解,请看下图:

初见该图,貌不惊人,但是如果使用OOP设计跑车类呢?

换而言之,它具有作为交通工具,作为一辆车的所有特点?具有所有的属性和行为?答案显而易见。思考一下,作为一辆跑车,是否首先是一辆交通工具,然后是否一定是一辆车?如果我们将“车”划分为“跑车”和“卡车”等等,将更加抽象的事物划分为更具体的事物,我们就称他们为父类和子类。

我们将这句话中的属性和行为用成员变量和成员方法置换,就成了“子类具有父类所有的成员变量和成员方法”。

这就是所谓“继承”,子类继承父类所有的属性和行为。在Java中,用extends关键字表示。

Example code:

class Animal {
private int age;
Animal(int age) {
this.age = age;
}
public void shout() {
System.out.println("I'm shout");
}
}
class Dog extends Animal {
Dog(int age) {
super(age);
}
}

而“多态”建立在“继承”的基础上,多态,字面源于希腊文字,polymorphism,它所有的意思可以归结为:父类类型的对象可以引用子类类型的对象(常见的两种方式),可以参考实例代码。

那怎么理解多态呢?

每个圆都是一个几何对象,但并非每个几何对象都是圆。

每个子类的对象必定是其父类的对象,因此给子类对象可以是父类声明。

class Demo1{
//父类
}
class Demo2 extends Demo1 {
//子类
}
public class Demo{
public static void main(String[] args){
Demo1 d1 = new Demo2();//第一种方式
Demo2 d2 = new Demo2(); //第二种方式
test(d2); //往test方法传一个Demo2对象
} public static void test(Demo1 d){
//由于Demo1是Demo2的父类,因此在接收参数时可以接收Demo2类的对象
}
}

而多态还有一个必须要get的点-----动态绑定机制!

若一个对象使用父类类型声明,只能调用父类中存在的方法,若子类的方法覆盖了父类的方法,则调用子类中的方法。直接上代码:

class Person{
public void say(){
System.out.println(“I’m a person”);
}
}
class Boy extends Person {
public void say(){
System.out.println(“I’m a Boy”);
}
public void do(){
}
}
public class Demo{
public static void main(String[] args){
Person p = new Boy();
p.say(); //调用的是Boy类的say()方法。
p.do();//编译错误
}
}

首先要明确一个定义:当子类中存在与父类的方法方法签名相同的方法时,父类的方法将被隐藏,这一过程称为覆盖

若一个对象使用父类类型声明,调用该对象的方法时,若存在子类的方法覆盖父类的方法,将调用子类的方法。

而且必须需要注意,由于使用的是父类的声明,因此只能调用父类中有声明过的方法,如图中代码p.do();do()只存在于子类中,因此会出现编译错误。

三、简化的多继承:单继承+接口(interface)

曾有一位朋友戏称多继承“100年用不到1次”,大多数情况下,使用单继承即可解决实际问题。因此笔者认为Java单继承+接口是更加实用的解决方式。学习接口之前,我们有必要了解一下何为“抽象类”。

抽象类代表拥有抽象方法的类,而抽象方法指的就是”在子类中必须要实现的方法”。使用关键字abstract实现。抽象类的存在有什么作用?

For example,每个几何对象都有自己的面积,那么必有一个成员方法,该方法可以返回它面积。但是每一种几何图形的计算方法都不一样,这时我们必须要有一个抽象方法,强制该类的子类实现该方法,同时由于该方法无法确定,几何图形类不得实例化。

abstract class GeometricObject {
public abstract double getArea();
} class Circle extends GeometricObject {
private double r; Circle(int r){
this.r = r;
} public double getArea() {
return Math.PI * r * r;
}
}
public class Demo {
public static void main(String[] args) {
GeometricObject c = new Circle(3);
c.getArea();//基于动态绑定,返回9*PI
}
}

接口与抽象类十分类似,这是从两个方面上来说的。

1.接口中的方法都为抽象方法,实现该接口的类必须实现接口中包含的方法。

2.接口定义了一种新的类型,且不得实例化。

作为多继承的替代品,接口所代表的实际意义是用来定义具有某些特定行为的类型。

它定义了一种新类型!正是因为它定义了一种新的类型,才能与继承配合达到多继承的效果!

观察下以下代码:

interface Sortable{
void sort();
}
class Stack implements Sortable{
//,,,
public void sort() {
//...
}
}
class Queue implements Sortable {
//,,,
public void sort() {
//...
}
}
public class Algorithms {
public static void main(String[] args) {
Sortable s1 = new Stack();
Sortable s2 = new Queue();
sort(s1);
sort(s2);
}
public static void sort(Sortable s) {
s.sort();
}
}

由于Stack和Queue类都实现了Sortable接口,因此Sortable是他们的父类型,可以使用Sortable声明,并且可以传入类型为Sortable的方法。值得一提的是,就像前面动态绑定机制提到的,由于声明类型为Sortable,只能调用Sortable声明过的方法。

java自带的库中存在着一种接口,这种接口不存在任何方法,我们称之为标记接口,比如Cloneable接口,有些朋友会有些奇怪,既然没有方法,那么有什么作用?

但是我们不要忘了接口定义了一种新的类型,只要实现了某个接口,我们就可以判断出它是否是该接口类型!只需使用instanceof关键字即可判断!

比如前面的代码可以改一下:

interface Sortable{
void sort();
}
class Stack implements Sortable{
//,,,
public void sort() {
//...
}
}
class Queue implements Sortable {
//,,,
public void sort() {
//...
}
}
public class Algorithms {
public static void main(String[] args) {
Sortable s1 = new Stack();
Sortable s2 = new Queue();
sort(s1);
sort(s2);
}
public static void sort(Object o) {
if(o instanceof Sortable) {
Sortable s = (Sortable)o;
s.sort();
}
}
}

PS:博客刚开,心情有点小激动,估计每星期会有1-2篇博客。有什么错误欢迎指正。

javaSE ---OOP总结的更多相关文章

  1. javaSE基础05

    javaSE基础05:面向对象 一.数组 数组的内存管理 : 一块连续的空间来存储元素. Int [ ] arr = new int[ ]; 创建一个int类型的数组,arr只是一个变量,只是数组的一 ...

  2. JavaSE之概述与基本语法

    嘛,这个本来应该发在OOP之前的,无所谓了,补发一下,这篇文章只会对JavaSE的语法做一个基本的概述而已,我会在最近新开一个新坑,也就是JavaEE系列,以后还会有Cpp(相对于C++,我还是更喜欢 ...

  3. 零基础入门学习javase,应该怎么学?这是我给你的一个建议

    我们知道Java有三个方向,JavaSE,JavaME,JavaEE(老程序员可能会叫J2EE等,不过SUN已经改名了).JavaME主要是嵌入式与游戏开发.那我们先看JavaSE,因为只有学好了Ja ...

  4. javaSE总结

    1 java的历史 1991-至今  詹姆斯-高斯林  SUN公司 ORACLE 2009年 2 java的版本 javaSE  java的标准桌面级开发 javaEE  企业级web开发 javaM ...

  5. JavaSE回顾及巩固的自学之路(四)——————方法和数组,面向对象

    今天是2018.03.31,emmmmmm.好像距离上一次写Javase回顾总结已经好久好久过去,差一点就以为要停更了,哈哈哈.        其实呢,最近是真的好忙(额,这段时间觉得自己一直在学习) ...

  6. JavaSE 面试题总结

    一. JavaSE 4 1. 面向对象的特征有哪些方面 4 2. String是最基本的数据类型吗? 4 3. super()与this()的区别? 4 4. JAVA的事件委托机制和垃圾回收机制 4 ...

  7. JavaSE核心知识

    一:Java简介 1. Java语言的介绍:Java是一门面向对象编程语言,具有功能强大和简单易用两个特征. 2. Java语言的特点:简单性.面向对象.分布式.健壮性.安全性.平台独立与可移植性.多 ...

  8. JavaSE理论篇

    将已学过的知识记录在此,既能便于以后温习又能方便知识共享,做到共同成长. 计算机语言发展简史 主要分为三个阶段 机器语言:打点机,有点表示1,没有表示0,打点计时器 低级语言:汇编语言 高级语言:Ja ...

  9. javaSE高级篇7 — 设计原则和设计模式 — 设计模式慢慢更( 这是思想层次篇 )

    1.什么是设计原则? 设计原则就是面向对象的原则嘛,即:OOP原则 换句话说:就是为了处理类与类之间的关系( 包括接口.类中的方法 ) 2.OOP设计原则有哪些? 1).开闭原则:就是指对拓展开放.对 ...

随机推荐

  1. go语言常用函数:make

    创建数组切片 Go语言提供的内置函数make()可以用于灵活地创建数组切片.创建一个初始元素个数为5的数组切片,元素初始值为0: mySlice1 := make([]int, 5) 创建一个初始元素 ...

  2. 关于Canvas模糊的问题

    前言:当我在几个多月前,第一次在移动设备上使用canvas绘制内容的时候,我惊然地发现我绘制的图片以及文字居然都是模糊的!我的内心几乎是崩溃的,因为那是我第一个使用canvas的项目,是一个基于微信端 ...

  3. 操作系统开发系列—13.d.多进程 ●

    进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态 ...

  4. 复杂sql分组查询 ( pivot)

    一个数据表里面字段有年.月.日.金额.支付方式等字段,然后现在想写个sql语句,把每一天的每种支付方式金额(支付方式有多重)排在同一行, 最后在增加一列小计当前的所有支付方式的金额.如下图: 原sql ...

  5. 解决Dialog 消失,输入法不消失的问题

    前言:今天遇到一个奇怪的问题,Activity 里面弹出一个 dialog , 这个dialog里面有EditText . 问题:当 dialog 里面的输入法出现的时候,此时让diolog 消失,输 ...

  6. Swift-Switch穿透

    switch vegetable {        case "celery":            print("Add some raisins and make ...

  7. 软件测试人员必备Linux命令(初、中、高级)

    有些技能可以事半功倍,有些命运掌握在我们手中.熟练的掌握和使用这些命令可以提高工作效率,并且结合这些命令对测试过程中遇到的问题进行一些初步的定位. 1 目录与文件操作1.1 ls(初级)使用权限:所有 ...

  8. nodejs events模块

    var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); console.log(emi ...

  9. 1.10 基础知识——GP3.1 制度化 & GP3.2 收集改进信息

    摘要: GP3.1是要求建立组织级的关于该过程的制度.标准.模版等全套体系,要求覆盖该PA所有的SP和GP.GP3.2 体现的是持续改进,每个过程都应该收集相应的改进信息. 正文: GP3.1 Est ...

  10. WebMatrix之WebMatrix.Data

    WebMatrix之WebMatrix.Data WebMatrix数据访问系列目次: WebMatrix之数据访问 WebMatrix之WebMatrix.Data WebMatrix之WebMat ...