------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
· 面向对象是相对面向过程而言
· 面向对象和面向过程都是一种思想
· 面向过程
强调的是功能行为
· 面向对象
将功能封装进对象,强调具备了功能的对象
· 面向对象是基于面向过程的
例:功能是将东西存储进冰箱。面向过程的思想就是先打开冰箱,存储事物,关闭冰箱;如果是面向对象的思想,将打开、储存、关闭都封装在冰箱里。就成为了,冰箱.打开 冰箱.存储 冰箱.关闭
· 是一种符合人们思考习惯的思想
· 可以将复杂的事情简单化
· 将程序员从执行者转换成了指挥者
· 完成需求时:
a. 先要去找具有所需功能的功能对象来使用
b. 如果该对象不存在,那么创建一个具有所需功能的对象
c. 这样简化开发提高了代码的复用
· 开发的过程:其实就是不断的创建对象,使用对象,指挥对象做事情
· 设计的工程:其实就是在管理和维护对象之间的关系
· 面向对象的特征:
a. 封装(encapsulation)
b. 继承(inheritance)
c. 多态(polymorph)
· 面试题:面向对象是什么?
答:面向对象是一种思想,可以让复杂的事情简单化,将执行者变成指挥者。举例一般可以随着实际场景出发。比如公司招人就是一种面向对象的思想,调用的就是招聘者身上的工作的功能
· 使用计算机语言就是不断的在描述现实生活中的事物
· java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义
· 对象即是该类事物实实在在存在的个体
· 类与对象的关系如图示例:
· 可以理解为:类就是图纸,汽车就是堆内存中的对象
· 生活中描述事物无非就是描述事物的属性和行为
如:汽车会有排量,颜色等属性
· java中用类描述事物也是如此
属性:对应类中的成员变量
行为:对应类中的成员函数
如:描述汽车(排量,颜色)。
· 定义类其实在定义类中的成员(成员变量和成员函数)
· 成员变量,作用于整个类中;在堆内存中,因为对象的存在而存在;有默认初始化值
· 局部变量,局部变量作用于函数或者语句中,存在于栈内存中
class Car { //对Car这类事物进行描述 String color = "red"; int num = 4; void show() { Ststem.out.println(“color=”+color+”..num=”+num); } }
class CarDemo { public static void main(String main[]) { Car c = new Car();//建立对象 c.color = “black”;//对对象的属性进行修改 c.show();//使用对象功能 } }
Car c1 = new Car(); c1.color="blue";
Car c2 = new Car();
c1、c2的引用存在于栈内存中,当执行到new Car()时,才在堆内存中建立实体,并根本这类事物,一开始c1的初始化color为"blue"。执行到c1.color="blue"时,在堆内存把red换为blue
· 匿名对象是对象的简化形式
· 匿名对象两种使用情况
a. 当对象方法仅进行一次调用时。例:new Car().show();
b. 匿名对象可以作为实际参数直接传递。例:有一个run(Car c)的方法,可以直接写成run(new Car());
· private是一个权限修饰符,用于修饰成员(成员变量和成员函数)。被私有化的成员只在本类中有效
· 常用之一:将成员变量私有化,对外提供get和set方法进行访问,提高数据访问的安全性
a. 函数名和类名相同
b. 不用定义返回值类型
c. 不可以写return语句
· 对象一建立就会调用与之相对应的构造函数,所以构造函数的作用:可以用于给对象进行初始化动作。
· 当一个类没有定义构造函数时,那么系统会默认给该类加入一个空参数构造函数
· 当在类中自定义了构造函数后,默认的构造函数就没有了
· 构造函数和一般函数在写法上不同,在运行上也不同。构造函数是对象一建立就运行,给对象进行初始化。而一般方法是对象调用才执行,给对象添加对象需要具备的功能。一个对象的建立,其构造函数只运行一次,而方法可以被多次调用。
· 什么时候定义构造函数?当分析事物时,该事物存在具备一些特性或者功能,那么将这些内容定义在构造函数中,
总结:根据构造函数的参数不同,所对应的构造函数也不同。当自己写了构造函数后,系统就不会添加默认构造函数。当创建对象时,会根据参数选择对应的构造函数并进行初始化动作。如果一个函数不想被创建对象,自己写一个空参数的构造函数并私有化。
作用:给对象进行初始化。对象一建立就运行,并且优先于构造函数。
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
例:有一个功能要在所有构造函数内容运行之前都要运行,就可以写在构造代码块中运行。这样所有的构造函数在运行前都会先运行构造代码块中的内容。
· 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
· 好处:
a. 将变化隔离
b. 便于使用
c. 提高重用性
d. 提高安全性
· 封装原则:
a. 将不需要对外提供的内容隐藏起来
b. 把属性隐藏,提供公共方法对其访问
· 例:电脑的主机相对于我们来说就是被封装的,电脑里面的硬件都是封装在电脑的机箱里面的。这样,电脑里面不管是换了什么硬件,对我们来说是没关系的,这就是将变化隔离的特性。把内容封装之后,提供固定的对外的接口让我们使用,这就提高了使用性。不能对内部进行操作,也是提高了安全性。
· 代码实例:需求:描述一个人的类。人有年龄。但是年龄需要一个合理的值,所以可以把年龄封装在人的类中。提供对外访问的方法对年龄进行操作。在设置方法中在对年龄进行逻辑判断
class Person { private int age; //对外提供get,set方法 public void setAge(String age) { if(age>0 && age<130) this.age= age; else System.out.println(“年龄非法”); } public int getAge() { return age; } }
this:代表本类对象,代表它所在函数所属对象的引用。简单地说,哪个对象在调用this所在的函数,this就代表哪个对象。
· 什么时候使用this关键字呢?
当定义类中功能时,该函数内部要用到该函数的对象时,这时用this来表示这个对象。但凡功能内部使用了本类对象,都用this表示。
· this关键字的应用:例:一个Person对象中有age属性,并在创建的时候就需要赋值。现在需要一个方法判断两个对象中的age是否相同。
在main函数中,这样写:
Person p1 = new Person(20);
Person p2 = new Person(25);
p1.compare(p2);
在Person中compare方法:
public boolean compare (Person p) {
return this.age = age;
}
在这个方法中,因为是p1调用的这个方法,所有this代表的是p1
· this关键字在构造函数间调用:
this() 用于构造函数之间的传递,并且只能定义在构造函数的第一行,因为初始化要先执行。
例:在Person中有2个构造函数Person(String name) {
this.name = name;
}
Person(String name,age) {
this(name);
this.age = age;
}
这段代码的this.name就是在构造函数中传递这个name参数。
当我们对外只提供很少的构造函数时,自己内部可以使用大量的构造函数。这时就可以使用这种this的使用情况!
例2:在Person中有2个构造函数,
Person() {
this(“a”);
};
Person(String name) {
this();
}
这种情况是不允许存在的。无限死循环....
· 是一个修饰符,用于修饰成员(成员变量和成员函数)
· 被修饰的成员具备以下特点:
a. 随着类的加载而加载。也就是说,静态会随着类的消失而消失
b. 优先于对象存在。明确一点,静态是先存在,对象是后存在的
c. 被所有对象共享
d. 可以直接被类名调用:类名.静态成员
e. static修饰的类,存放在方法区(共享区,数据区)
1. 存放位置:类变量随着类的加载而存在于方法区中;实例变量随着对象的建立而存在于堆内存中
2. 生命周期:类变量生命周期最长,随着类的消失而消失;实例变量生命周期是随着对象的消失而消失
· 静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态
· 静态方法中不可以写this、super关键字。因为静态优先于对象存在,所以静态方法中不可以出现this
· 主函数是静态的
· 是一个特殊的函数。作为程序的一个入口,可以被句jvm调用。
· 主函数的定义:
public:函数访问权限最大
static:代表主函数随着类的加载就已经存在了
void:主函数没有具体返回值
main:不是关键字,但是是一个特殊的单词,可以被jvm识别
(String args[]):函数的参数,参数类型是一个数组。该数组中元素是字符串。args是可以修改的,变量名只要合法就行。原先是argument
· 主函数的格式是固定的:jvm识别
· 好处:
a. 对对象的共享进行单独空间的存储,节省空间。没有必要每一个对象都要存储一份
b. 可以直接被类名调用
· 弊端:
a. 生命周期过长
b.访问出现局限性,因为静态只能访问静态
· 每一个应用程序都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用
· 如果我们有一个工具类,可以把工具类中所有的方法都定义成static的,直接通过类名调用
· 通过javadoc -d myhelp -author -version 类名.java 编写说明书
· 格式:
static {
静态代码块中执行的语句;
}
· 特点:随着类的加载而执行,只执行一次
1,因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化
3,在堆内存中开辟空间,分配内存地址
4,在堆内存中建立对象特有的属性,并进行默认初始化(姓名,年龄)
5,对属性进行显示初始化
6,对对象进行构造代码块初始化
7,对对象进行对应的构造函数代码块初始化
8,将内存地址赋给栈内存中的p变量
七,扩展知识——设计模式· 单例设计模式:解决一个类在内存中只存在一个对象
· 想要保证对象的唯一性:
a. 为了避免其他程序过多建立该类对象,先禁止其他类创建该对象
b. 还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象
c. 为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
· 用代码实现:
a. 将构造函数私有化
b. 在类中创建一个本类对象
c. 提供一个方法可以获取到该对象
· 代码:
class Single {//饿汉式,类一进内存,就已经创建好对象 private static Single s = new Single(); private static () {} public static Single getInstance() { return s; } }
class Single {//懒汉式,对象是方法被调用时才初始化。这也叫类的延时加载 private static Single s = null; private Single() {} public static Single getInstance() { if(s==null) { synchronized(Single.class) { if(s==null) { s = new Single(); } } } return s; } }