1.面向过程和面向对象
面向过程和面向对象都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。
面向过程:思考问题时,我们首先思考“怎么按步骤实现?”并将步骤对应成方法,一步一步,最终完成。这个适合简单任务,不需要过多协作的情况下。
面向对象:思想更契合人的思维模式,我们首先思考的是“怎么设计这个事物?”
面向过程和面向对象的总结:
1.都是解决问题的思维方式,都是代码组织的方式;
2.解决简单问题可以使用面向过程;
3.解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。——相辅相成
2.对象
对象(object):可以看作数据管理的方式。在内存中,就是一个内存块。——object instance(实例)
类:可以看作是一个模板,系统根据类的定义来造出对象;——class
组成:
- 属性(field)或成员变量:用于定义该类或该类对象包含的数据或者说静态特征;属性作用范围是整个类体;
- 方法:用于定义该类或该类实例的行为特征和功能实现;
2.1 构造方法
要点:
- 通过new关键字调用;
- 构造器虽然有返回值(new之后返回new的对象),但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值(可以直接return);
- 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义,则编译器不会自动添加;
- 构造器的方法名必须和类名一致。
和其它方法一样,构造方法也可以重载。
构造方法第一句总是:**super()**来调用父类对应的构造方法。会先向上追溯到Object的构造方法,然后依次向下执行类的初始化块和构造方法,直到当前子类为止。
2.2 this的本质
创建一个对象分为如下4步:
- 分配对象空间,并将对象成员变量初始化为0或空;
- 执行属性值的显式初始化;
- 执行构造方法;
- 返回对象的地址给相关的变量;
this的本质就是“创建好的对象的地址”!由于构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象”。
this最常用的用法:
- 在程序中产生二义性之处,使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象;
- 使用this关键字调用重载的构造方法,避免相同的初始化代码。此时,只能在构造方法中用,并且必须位于构造方法的第一句;
public class Test {
int a, b, c;
public void Test(int a, int b) {
this.a = a;
this.b = b;
}
public void Test(int a, int b, int c) {
this(a,b);
this.c = c;
}
}
- this不能用于static方法中(因为static方法为所有对象共有);
2.3 static关键字
在类中,用static声明的成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同,在整个程序执行期间都有效。
2.4 静态初始化块
静态初始化块:用于类的初始化操作!在静态初始化块中不能直接访问非static成员。
注意:
- 会先上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到最后执行我们的类的静态初始化块为止。
- 构造方法执行顺序和上面的顺序一样。
- 先执行静态初始化块(加载类), 再执行构造方法;
2.5 Java的参数传值机制——值传递
传对象:传地址
2.6 Java包机制
包机制是Java中管理类的重要手段。开发中,我们会遇到大量同名的类,通过包我们很容易解决类重名的问题,也可以实现对类的有效管理。包对于类,相当于文件夹对于文件的作用。
通过package实现对类的管理,package的使用有两个要点:
- 通常是类的第一句非注释性语句;
- 包名:域名倒着写即可,再加上模块名,便于内部管理类;
使用import导入其它包的类。
import .*; //导入该包下的所有的类。会降低编译速度(编译只有一次),但不会降低运行速度。
import static:静态导入,其作用是用于导入指定类的静态属性,这样便可以直接使用静态属性。
2.7 继承 extends
2.7.1 继承
优点:实现了代码的重用
使用要点:
- 父类也称为超类、基类、派生类。
- Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
- Java中类没有多继承,接口有多继承。
- 子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法),但不见得可以直接访问。比如,父类私有的属性和方法。
- 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
2.7.2 instanceof运算符:
是二元运算符,左边是对象,右边是类。当对象是右边类或其子类所创建的对象时,返回true;否则,返回false。
2.7.3 Object类
Object类是所有Java类的根基类,即所有的Java对象都拥有Object类的属性和方法。
2.7.4 super父类对象引用
super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。
2.7.5 方法的重写(覆盖) Override
子类通过重写父类的方法,可以用自身的行为替换父类的行为。
方法重写需要符合下面的三个要点:
- “==”:方法名、形参列表相同;
- “<=”:返回值类型和声明异常类型,子类小于等于父类;
- “>=”:访问权限,子类大于等于父类。
2.7.5.1 equals方法的重写
“==”:代表比较双方是否相同。如果是基本类型则表示值相等;如果是引用类型则表示地址相等,即是同一对象。
2.8 封装(encapsulation)
封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
程序设计追求“高内聚、低耦合”。
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;
低耦合是仅暴露少量的方法给外部使用,尽量方便外部调用。
编程中封装的具体优点:
- 提高代码的安全性;
- 提高代码的复用性;
- “高内聚”:封装细节,便于修改内部代码,提高可维护性;
- “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作。
2.8.1 封装的实现——使用访问控制符
Java使用“访问控制符”来控制哪些细节需要封装,哪些细节需要暴露的。Java中4种“访问控制符”分别为private、protected、public和default,它们说明了面向对象的封装性,我们需要利用它们尽可能地让访问权限降到最低,从而提高安全性。
修饰符 | 同一个类 | 同一个包中 | 子类 | 所有类 |
---|---|---|---|---|
private | * | |||
default | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
- private表示私有,只有自己类能访问;(子类拥有父类的私有属性和方法,但是“看不见”,无法使用)
- default表示没有修饰符修饰,只有同一个包的类能访问;
- protected表示可以被同一个包的类以及其它包中的子类访问;
- public表示可以被该项目的所有包中的所有类访问。
javabean:
没有复杂逻辑的简单类,就包含类属性(private)及get、set方法(public)。
2.9 多态(polymorphism)
多态指的是同一个方法调用,由于对象不同可能会有不同的行为。
多态的要点:
- 多态是方法的多态,不是属性的多态(多态和属性无关)。
- 多态的存在有3个必要条件:继承、方法重写、父类引用指向子类对象。
- 父类引用(函数参数?)指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
2.10 对象的转型(casting)
- 向上转型,属于自动类型转换。
- 向下强制转型。
class Test {
public static void main(String[] args) {
Animal a = new Dog(); //向上自动转型,**编译时编译器认为a为Animal**,运行时实际为dog,所以a不能调用Dog中特有的方法
a.watchDoor(); //报错,无法编译成功
Dog d = (Dog) a; //向下强制转型
d.watchDoor(); //此时,可以成功编译
}
}
class Animal {
public void shout() {
System.out.println("叫!!!");
}
}
class Dog extends Animal {
public void shout() {
System.out.println("汪!!!");
}
public void watchDoor() {
System.out.println("看门!!!");
}
}
2.11 final关键字
- 修饰变量:被它修饰的变量不可改变,一旦赋了初值,就不能被重新赋值;
- 修饰方法:该方法不可被子类重写,但可以被重载;
- 修饰类:被修饰的类不能被继承。如,Math、String等。