一、面向对象的概念
1、如何理解面向对象(面向对象的特点)?
(1)面向对象是一种常见的思想,符合人们的思考习惯
(2)面向对象的出现,将复杂的问题简单化
(3)面向对象的出现,让曾经在过程中的执行者,变成了面向对象思想中的指挥者+eg
2、面向过程没有被淘汰:面向对象基于面向过程,是将过程封装在一个对象身上,然后通过对象找到这些功能。如果对象有这些功能就直接拿来用,如果没有,不是去写一个功能,而是造一个对象具备该功能
3、在做开发时,要先找到数据所属的对象。遇到问题时,要先分析问题中涉及到哪些对象,而不关注问题所涉及的动作有哪些。解决问题时,尽量找具备这些功能的对象来完成,如果没有,就自己创建一个具备这些功能的对象来解决。后期要不断地去维护对象之间的关系--有对象找对象,没对象造对象
4、面向对象的三个基本特征:封装、继承、多态。只有符合这三个特征,才能称为使用面向对象的思想
5、名词提炼法:一般名词都是对象
6、当创建对象时,功能定义在哪个对象中最合适,看哪个对象对动作最清楚就将功能定义在哪个对象中
7、用面向对象来思考问题的特点:尽量以对象为核心,先分析有哪些对象。将功能封装在对象中,想用功能,先找对象
二、类与对象
1、类与对象的关系
类:事物的描述,是抽象的概念(具有相同属性和方法的一组对象的集合)
对象:该类事物的实例,是实实在在存在的个体。在Java中是通过new来创建的
对于事物的描述,通常只关注两个方面,一个是属性,一个是行为。一旦产生一个对象,这个对象就具备类中所描述的全部内容
2、成员分两种,成员变量(属性)和成员函数(行为)。定义类其实就是在定义类中的成员(成员变量和成员函数)
3、成员变量和局部变量的区别
(1)成员变量定义在类中,整个类中都可以访问(类中的所有方法共享成员变量)
局部变量定义在函数、语句、局部代码块中,只在所属的区域有效
(2)成员变量存在于堆内存的对象中
局部变量存在于栈内存的方法中,临时保存数据
(3)成员变量随着对象的创建而存在,随着对象的消失而消失(此对象中的成员变量存在或消失,与其他对象的成员变量无关)
局部变量随着所属区域的执行而存在,随着所属区域的结束而释放
(4)成员变量有默认初始化值(不初始化也可以使用,String类型变量的默认初始化值为null)
局部变量没有默认初始化值(不初始化不可以使用)
4、类中的成员变量是在描述所有对象都具有的属性,赋值/输出 是针对具体某个对象,与其他对象、类中的成员变量无关
5、局部变量和成员变量同名时,局部变量优先。自己所属内存区域中有,就不去外面找。栈内存中有,就用栈内存中的。栈内存中没有,就去堆内存中找。堆内存中也没有,就报错
6、匿名对象(简化书写)的使用方式
(1)当对象对方法仅进行一次调用时,可以简化成匿名对象(new一次就是创建一个对象)
注:对象调用 变量 时不能使用匿名对象是因为:匿名对象没有任何引用变量所指向,它运行完就结束了,用匿名对象调用变量没有任何意义。而匿名对象调用方法时,可以执行方法中的内容
(2)匿名对象可以作为实际参数进行传递。此时必须有一个类类型的引用变量接收这个匿名对象,该匿名对象被接收它的引用变量所指向,不会变成垃圾
三、构造函数
1、构造函数:在构建创造对象时调用的函数(创建的对象都必须要通过构造函数初始化,所以,一创建对象,构造函数就被调用了,被对象调用)
作用:给对象进行初始化(对象一创建出来,就具备一些内容)
何时使用:在描述事物时,该事物一存在就具备的内容,需要定义在构造函数中
2、构造函数的语句格式
权限(与类的权限相同) 构造方法名/类名 ( 可以指定参数 ){
//初始化代码
}
3、构造函数的特点
(1)函数名与类名相同
(2)不用定义返回值类型
(3)没有具体的返回值
4、默认构造函数
(1)一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数
(2)如果在类中定义了指定的构造函数(无论是有参还是无参的构造函数),那么类中的默认构造函数就没有了
即 如果定义了一个有参的构造方法,但却用无参的构造方法创建对象,系统编译报错,因为系统此时没有帮忙创建默认的无参构造函数
5、编译器编译完以后,xxx.class文件中就包含构造函数了,编译器会做检查
6、构造函数和一般函数的区别
(1)构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化(对象创建时一定要进行初始化)
一般函数:对象创建后,需要该函数功能时才调用
(2)构造函数:对象创建时,会调用且只调用一次(构造函数是用来初始化对象的,对象初始化完毕后再调用构造函数没有意义)
一般函数:对象创建后,可以被调用多次
(3)构造函数和一般函数不冲突。构造函数在对象创建时只调用一次,初始化完具备的内容如果需要修改,则需要调用一般方法
7、构造函数的重载
(1)一个类中可以有多个构造函数,给不同的对象进行不同的初始化
(2)多个构造函数在一个类中出现,它们的存在形式就只能有一种:重载(方法名相同,参数列表不同)
即 一个类中出现多个构造函数时,它们必须以重载的形式来体现,可以对不同的对象进行不同的初始化
8、构造函数可以直接调用一般方法,但一般方法不能直接调用构造函数(构造函数是用来给对象进行初始化的,函数得需要对象才可以进行调用)
9、如果在构造函数前加void,就会变成一般函数,不再是构造函数了。此时是可以编译通过的
10、构造函数中有return语句,但不常写
11、构造方法不但可以给对象的属性赋值,还可以保证给对象的属性赋一个合理的值 -- 在构造函数中加if判断
12、构造函数的权限和其所在类的权限相同。如果类的权限是public/默认权限,则该类构造函数的权限也是public/默认权限
四、this
1、this的作用
(1)当局部变量和成员变量重名时,可以用关键字this来区分。this就是所在函数所属对象的引用,this代表当前对象,但它不是对象(哪个对象调用了this所在的函数,this就代表哪个对象)-- new时先开辟空间、分配地址值,再进行初始化
注:凡是被对象调用的方法,它们都持有一个this引用
(2)用于在构造函数中调用其他构造函数,但只能定义在构造函数的第一行,因为初始化动作要先执行( 用法:this(参数列表)。构造函数是给对象初始化的,对象不确定,用this表示。代表哪个对象,用构造函数的参数列表决定 --构造函数的区分是通过参数列表来完成的 ) -- 分步初始化
注:一个类中,它的所有成员想要运行,都必须用对象进行调用(静态除外)
(3)只要用到本类的对象在本类中(只要方法中用到了本类的对象),通常都用this,因为this代表本类对象
五、static
1、被静态static修饰的数据,是被所有对象共享的数据。而对象内部封装的数据,都是对象的特有数据(没有被静态修饰的叫非静态)
2、static的特点
(1)static是一个修饰符,用于修饰成员 --变量、方法、代码块
(2)static修饰的成员被所有对象共享
(3)static优先于对象存在(共享数据会在对象之前出现)。因为static修饰的成员是随着类的加载就已经存在了,而类加载时不一定有对象
(4)static修饰的成员多了一种调用方式,不仅可以被对象调用,还可以直接被类名调用(可以不用创建对象就能调用成员)。调用格式:类名.静态成员
(5)static修饰的数据是共享数据,在对象中存储的数据是特有数据(有些数据是共性的、共享数据,有些数据是特有的,需要被对象封装在内部)
3、成员变量和静态变量的区别
(1)两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的被回收而释放
静态变量随着类的加载而存在,随着类的消失而消失(生命周期长,但可以节省内存空间)
注:静态变量随着类加载完成初始化,它在内存中仅有一个,JVM也只为它分配一次内存。同时,类所有的实例都共享静态变量
(2)调用方式不同
成员变量只能被对象调用
静态变量可以被对象调用,也可以被类名调用(静态变量建议使用类名调用,因为不需要对象,且类名调用是静态变量的专属调用方式,阅读性较好)
(3)别名不同
成员变量也叫实例变量
静态变量也叫类变量
(4)数据存储位置不同
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据(堆内存中存放的都是实体,对象中的变量在堆内存中而不在栈内存)
静态变量数据存储在方法区的静态区中,所以也叫对象的共享数据(方法存在方法区中。方法区相当于一个共性数据的存储区 -- 也叫共享数据区。方法区更细分为静态区和非静态区,静态区用来存储静态成员)
即 静态方法和非静态方法都在方法区中。而方法区的静态区中存储的除了静态方法,还有静态变量(默认初始化和显示初始化)
4、静态使用的注意事项
(1)静态方法只能访问静态成员,非静态既可以访问静态的,也可以访问非静态的。如果要在静态方法中调用非静态成员,可以通过创建类的对象,然后通过对象来访问非静态成员
(2)静态方法中不可以定义或使用this、super关键字,因为没有对象
(3)主函数main()是静态的(在主函数中访问别人需要创建对象后用对象调用成员 -- 对象是万能的)
(4)静态前面省略的是类名,非静态前面省略的是this
(5)static变量在定义时必须要进行初始化,且初始化时间要早于非静态变量???
5、方法区中,非静态区和静态区中的方法都是被共享的,唯一的区别是封装的数据不同(一个是对象共享的数据,一个是对象特有的数据),调用方式和所属不同(非静态区的所有成员都有一个this所属,静态区的所有成员都所属于自己的类名)
6、静态变量在编译生成 .class文件时,就已经有所属的类了(静态变量随着类的加载而存在)
7、static何时使用:
(1)静态变量:对象中对同一个成员变量具有相同的值,且值的改变共享,就将变量定义成静态的(定义成非静态的浪费存储空间)-- 如果一个对象的变量值改变,其他变量值不变,此时该变量不能定义成静态的
(2)静态方法:从内存上讲,函数功能是否访问到对象中的特有数据。从源代码上看,函数功能是否需要访问非静态的成员。如果方法没有访问特有数据,创建对象没有意义(对象是用来封装特有数据的)
注:方法不管是不是静态static的,其生命周期都一样,只不过一个所属于this,一个所属于类名
8、工具类中静态的使用
(1)静态的基本使用:方法没有访问特有数据时,将方法定义为静态的,直接用类名调用
(2)Java中有一些类只提供工具方法,不封装特有数据,这种类称为工具类,该类中一个非静态方法都没有。工具类中有一个默认的空参构造函数,但工具类创建对象没有意义(全静态)。为了阻止创建工具类对象,需要将构造函数私有
六、代码块
1、静态代码块:
(1)格式:static { ... }
(2)静态代码块随着类的加载而执行,且只执行一次(不管new多少个对象,类就只加载一次)。同时,静态代码块只能给静态变量赋值,不能初始化普通的成员变量
(3)静态代码块的作用:给类进行初始化。构造函数是给对象初始化的,创建对象时调用。有的类(全是静态)不需要对象,不能用构造函数进行初始化,此时调用静态代码块来完成初始化
注:可在静态代码块中对静态变量赋值。在定义静态变量时不直接对静态变量赋值,是因为此时除了赋值,其他的什么都做不了。但在静态代码块中,除了可以对静态变量赋值,还可以进行多次运算
(4)静态代码块用的不多,JDBC连接或在框架底层会用到
(5)用静态代码块初始化的类(随着类的加载而进行初始化的类),该类中一般全都是静态成员 -- 没有对象。但凡有非静态的成员,一般都不用静态代码块初始化,而是用对象去初始化,根据对象的不同初始化不同的内容
(6)若在主函数中定义静态代码块,谁先执行?
主函数所属类先进内存,而主函数被调用才执行
2、构造代码块:
(1)格式:{ ... },定义在类中
(2)构造代码块的作用:给所有对象进行初始化,创建几个对象就调用几次(对象一创建就具备的内容,定义在构造代码块或构造函数中)
(3)构造代码块具备着对象初始化的通用性(也可以初始化实例环境),构造函数具备着对象初始化的针对性 -- 将共性的代码抽取到构造代码块中,构造函数中定义的都是特性的代码
(4)构造代码块在构造函数之前执行
3、局部代码块:
(1)格式:{ ... },定义在方法中
(2)局部代码块的作用:限定局部变量的生命周期
4、执行顺序:静态代码块最先执行。若有对象,构造代码块再执行,最后执行构造函数、局部代码块
七、main函数
public static void main(String[] args) { ... }
1、public:权限必须是最大的
2、static:不需要对象,直接用主函数所属类名调用即可
3、void:主函数没有具体的返回值,返回给JVM也不处理
4、main:函数名,不是关键字,只是一个JVM识别的固定的名字
5、String[] args:函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型
注:public static void main(String[] args) { ... } 中,只有args是可以被改变的,因为是形参,其他的都是不能被改变的