JAVA面向对像做的一个简单的思维导图:
表格结构和类结构我们在现实生活中,思考问题、发现问题、处理问题,往往都会用“表格”作为工具。实际上,“表格思维”就是一种典型的面向对象思维。 实际上,互联网上所有的数据本质上都是“表格”。我们在这里通过从表格表示数据开始,引入对象和类。大家就会神奇的发现,原来“表格就是对象”。
面向过程和面向对象的区别面向过程和面向对象都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高,面向过程的弊端越来越明显的显示出来,出现了面向对象思想并成为目前主流的方式。两者都贯穿于软件分析、设计和开发各个阶段,对应面向对象就分别称为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)。C语言是一种典型的面向过程语言,Java是一种典型的面向对象语言。
面向对象是一种“设计者思维”。设计时,先从问题中找名词,然后确立这些名词哪些可以作为类,再根据问题需求确定的类的属性和方法,确定类之间的关系。 设计一款企业管理软件,我们需要进行面向对象分析(OOA:Object-Oriented Analysis),写一首诗、一篇文章、一篇小说也需要进行面向对象分析。 因此,面向对象这种思维是任何人都需要学习、任何人都需要掌握的。
类的定义:做了关于对象的很多介绍,终于进入代码编写阶段。本节中重点介绍类和对象的基本定义,属性和方法的基本使用方式。 属性(field 成员变量)属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化。
方法方法用于定义该类或该类实例的行为特征和功能实现。方法是类和对象行为特征的抽象。方法很类似于面向过程中的函数。面向过程中,函数是最基本单位,整个程序由一个个函数调用组成。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
构造方法基础用法构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应与类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。
构造方法的重载: 构造方法也是方法,只不过有特殊的作用而已。与普通方法一样,构造方法也可以重载。
Java虚拟机的内存可以简单的分为三个区域:虚拟机栈stack、堆heap、方法区method area。 虚拟机栈(简称:栈)的特点如下:1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)3. 栈属于线程私有,不能实现线程间的共享!4. 栈的存储特性是“先进后出,后进先出”5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!堆的特点如下:1. 堆用于存储创建好的对象和数组(数组也是对象)2. JVM只有一个堆,被所有线程共享3. 堆是一个不连续的内存空间,分配灵活,速度慢!方法区(又叫静态区,也是堆)特点如下:1. 方法区是JAVA虚拟机规范,可以有不同的实现。 i. JD7以前是“永久代”ii. JDK7部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中iii. JDK8是“元数据空间”和堆结合起来。2. JVM只有一个方法区,被所有线程共享!3. 方法区实际也是堆,只是用于存储类、常量相关的信息!4. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象,反射机制中会重点讲授】、静态变量、字符串常量等)
ava中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。· 基本数据类型参数的传值 传递的是值的副本。 副本改变不会影响原件。· 引用类型参数的传值 传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”。
this关键字对象创建的过程和this的本质构造方法是创建Java对象的重要途径,通过new关键字调用构造器时,构造器也确实返回该类的对象,但这个对象并不是完全由构造器负责创建。创建一个对象分为如下四步:1. 分配对象空间,并将对象成员变量初始化为0或空2. 执行属性值的显示初始化3. 执行构造方法4. 返回对象的地址给相关的变量 this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。 this最常的用法:q 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。q 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。q this不能用于static方法中。
static 关键字在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。它有如下特点:q 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。q 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!q 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)q 在static方法中不可直接访问非static的成员。
包机制(package、import)包机制是Java中管理类的重要手段。 开发中,我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。 包对于类,相当于文件夹对于文件的作用。package我们通过package实现对类的管理,package的使用有两个要点:1. 通常是类的第一句非注释性语句。2. 包名:域名倒着写即可,再加上模块名,便于内部管理类。
继承 继承是面向对象编程的三大特征之一,它让我们更加容易实现对于已有类的扩展、更加容易实现对于现实世界的建模。继承有两个主要作用:1. 代码复用,更加容易实现类的扩展2. 方便对事务建模
继承的实现继承让我们更加容易实现类的扩展。
继承使用要点1. 父类也称作超类、基类。子类:派生类等。2. Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。3. Java中类没有多继承,接口有多继承。 4. 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。5. 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
final关键字final关键字的作用:q 修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。final int MAX_SPEED = 120;q 修饰方法:该方法不可被子类重写。但是可以被重载!final void study(){}q 修饰类: 修饰的类不能被继承。比如:Math、String等。final class A {}
继承和组合我们可以通过继承方便的复用已经定义类的代码。还有一种方式,也可以方便的实现“代码复用”,那就是:“组合”。 “组合”不同于继承,更加灵活。“组合”的核心就是“将父类对象作为子类的属性”,然后,“子类通过调用这个属性来获得父类的属性和方法”。
super关键字super“可以看做”是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
继承树追溯·属性/方法查找顺序:(比如:查找变量h)q 查找当前类中有没有属性hq 依次上溯每个父类,查看每个父类中是否有h,直到Objectq 如果没找到,则出现编译错误。q 上面步骤,只要找到h变量,则这个过程终止。 ·构造方法调用顺序:构造方法第一句总是:super(…)来调用父类对应的构造方法。所以,流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。
封装(encapsulation) 封装是面向对象三大特征之一。对于程序合理的封装让外部调用更加方便,更加利于写作。同时,对于实现者来说也更加容易修正和改版代码。
封装的作用和含义我要看电视,只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?制造厂家为了方便我们使用电视,把复杂的内部细节全部封装起来,只给我们暴露简单的接口,比如:电源开关。具体内部是怎么实现的,我们不需要操心。需要让用户知道的才暴露出来,不需要让用户知道的全部隐藏起来,这就是封装。说的专业一点,封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。我们程序设计要追求“高内聚,低耦合”。 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合是仅暴露少量的方法给外部使用,尽量方便外部调用。
编程中封装的具体优点:q 提高代码的安全性。q 提高代码的复用性。q “高内聚”:封装细节,便于修改内部代码,提高可维护性。q “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作。
Java是使用“访问控制符”来控制哪些细节需要封装,哪些细节需要暴露的。 Java中4种“访问控制符”分别为private、default、protected、public,它们说明了面向对象的封装性,所以我们要利用它们尽可能的让访问权限降到最低,从而提高安全性。
private 表示私有,只有自己类能访问2. default表示没有修饰符修饰,只有同一个包的类能访问3. protected表示可以被同一个包的类以及其他包中的子类访问4. public表示可以被该项目的所有包中的所有类访问
封装的使用细节类的属性的处理:q 一般使用private访问权限。q 提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头!)。q 一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰。
多态概念和实现多态指的是同一个方法调用,由于对象不同可能会有不同的行为。现实生活中,同一个方法,具体实现会完全不同。 比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,高淇老师是敲代码,数学教授是做数学题; 同样是调用人“吃饭”的方法,中国人用筷子吃饭,英国人用刀叉吃饭,印度人用手吃饭。多态的要点:1. 多态是方法的多态,不是属性的多态(多态与属性无关)。2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
抽象方法和抽象类·抽象方法 使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。 ·抽象类 包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
抽象类的使用要点:1. 有抽象方法的类只能定义成抽象类2. 抽象类不能实例化,即不能用new来实例化抽象类。3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。4. 抽象类只能用来被继承。5. 抽象方法必须被子类实现。
接口interface接口就是规范,定义的是一组规则,
定义接口的详细说明:q 访问修饰符:只能是public或默认。q 接口名:和类名采用相同命名机制。q extends:接口可以多继承。q 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。q 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。
接口中定义静态方法和默认方法(JDK8以后)JAVA8之前,接口里的方法要求全部是抽象方法。JAVA8(含8)之后,以后允许在接口里定义默认方法和类方法。 1. 默认方法Java 8及以上旧版本,允许给接口添加一个非抽象的方法实现,只需要使用 default 关键字即可,这个特征又叫做默认方法(也称为扩展方法)。 默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供默认方法的实现,所有这个接口的实现类都会通过继承得到这个方法。
静态方法JAVA8以后,我们也可以在接口中直接定义静态方法的实现。这个静态方法直接从属于接口(接口也是类,一种特殊的类),可以通过接口名调用。如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类。可以通过子类名直接调用。
接口的多继承接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。
String是我们开发中最常用的类,我们不仅要掌握String类常见的方法,对于String的底层实现也需要掌握好,不然在工作开发中很容易犯错。
String基础q String类又称作不可变字符序列。q String位于java.lang包中,Java程序默认导入java.lang包下的所有类。q Java字符串就是Unicode字符序列,例如字符串“Java”就是4个Unicode字符’J’、’a’、’v’、’a’组成的。q Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String,每个用双引号括起来的字符串都是String类的一个实例。
字符串相等的判断q equals方法用来检测两个字符串内容是否相等。如果字符串s和t内容相等,则s.equals(t)返回true,否则返回false。q 要测试两个字符串除了大小写区别外是否是相等的,需要使用equalsIgnoreCase方法。q 判断字符串是否相等不要使用"=="。