Bootstrap

面向对象(JAVA)

本文详细介绍了java面向对象的相关知识,包括但不限于以下知识:

  1. 类与对象
  2. 面向对象三大特征:封装、继承、多态
  3. 面向对象三大修饰符:(final、abstract、static)


1.面向对象(类与对象)

1.编程思想

面向过程:
	考虑事物的发展顺序

面向对象:
	首先考虑事物中存在哪些对象,再建立对象与对象的关系

2.对象

(1)概念

	生活中:真实存在的事物就是对象
	代码中:使用代码模拟生活中存在的对象
	/*万事万物皆对象*/

(2)如何创建一个对象

	语法:
		数据类型(类名) 对象名 = new 类名(实参列表);
	本质:
		调用类中的构造函数,
	要求:
		调用构造函数时,传入的实参列表要与构造函数定义时的形参列表,长度一致,顺序一致,数据类型一致

(3)对象的创建过程

语法:
	类名 对象名 = new 类名(实参列表);

创建过程:
	1,在堆内存开辟一片运行内存
	2,给对象的属性赋初始值(基本数据类型默认为0(值存储在堆中),引用数据类型默认为null(存储的是引用数值所在的地址))
	3,执行构造函数中的代码
	4,将栈中的引用指向堆中开辟的内存地址

3.类

(1)概念

多个对象抽取其共同点形成的概念,就称为类

(2)如何创建一个类

	语法:
		访问权限修饰符 class 类名{
		
		}
		类名:符合大驼峰命名法,做到见名知意
	定义的位置:
		因为内部类还没有学习,所有将自定义类定义在 类 以外

(3)类中有什么


	属性概念:用于描述对象的静态特征
		别名:成员变量
		本质:就是在方法外,类中定义的变量
		定义的格式:
			访问权限修饰符 数据类型 变量名;
			注意:只能使用该类对象调用
			
	构造函数概念:用于创建该类对象,因为构造函数的方法名必须与类名一致,所以new调用的就是构造函数
		别名:构造方法
		本质:一个特殊的方法
		定义的格式:
			访问权限修饰符 类名(形参列表){
				方法体
			}
		定义位置:
			类中,方法以外
		注意:1.只能使用new关键字调用
			 2.如果一个类中没有构造函数,系统会为其提供一个无参的构造函数
			
	方法概念:用于描述对象的动态特征(行为)
		别名:函数
		本质:包装一段代码的容器
		定义的格式:
			访问权限修饰符 修饰符 返回值类型 方法名(形参列表){
				方法体
				return xxx;
			}
			返回值类型:如果方法有返回值,那么返回值类型就是返回值的数据类型,如果没有就写void
			方法名:自定义,符合小驼峰命名法
		定义位置:
			类中,方法以外
	
属性的作用:描述对象 静态特征
构造函数的作用:创建该类对象
方法的作用:描述对象的 动态特征

(4)类与对象的关系

生活中:
	先有对象后有类
	
代码中:
	现有类后有对象

(5)局部变量与成员变量

1.在类中的位置不同
	成员变量:在类中定义
	局部变量:在方法中定义或方法的参数

2.在内存中的位置不同
	成员变量:在堆内存(成员变量属于对象,对象进堆内存)
	局部变量:在栈内存(局部变量属于方法,方法进栈内存)

3.声明周期不同
	成员变量:随着对象的创建而存在,随着对象的销毁而消失
	局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

4.初始化值不同
	成员变量:有默认初始化值,引用数据类型默认为null
	局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
	
5.权限修饰符不同
    局部变量:无权限修饰符
    成员变量:存在权限修饰符	

注意:局部变量名称可以和成员变量名称一样,在方法中使用时,采用就近原则(若其为对象可以采用this区分)

(6)静态变量与成员变量的区别

静态变量:
	1. 调用方式:类名.属性名或对象名.属性名
	2.属于 该类 所有的对象
成员变量:
	1.调用方式:对象名.属性名
	2.属于 具体 的某一对象

(7)构造函数与方法的区别

1、格式区别
    构造方法和类名相同,并且没有返回类型,也没有返回值;不可被重写、不可被继承(可以被调用);可用thissuper调用本类和父类的构造函数。
    普通成员方法可以任意起名,必须有返回类型,可以没有返回值;可被重写、可被继承;不可用thissuper调用本类和父类的构造函数。
    
2、作用区别           
    构造方法用于创建对象,并进行初始化值。
    普通成员方法是用于完成特定功能的。
    
3、调用区别
    构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
    普通成员方法是由创建好的对象调用,可以调用多次

4.this的使用

(1)概念

哪一个对象调用this所在的方法,this就代指这个对象

(2)使用

	1,当局部变量与成员变量重名时,用于区分成员变量与局部变量,this.属性名表示成员变量(属性)
	
	2,在本类构造函数中,调用其他构造函数
		this(实参列表);
		注意:
			1,必须在构造函数第一行
			2,不要形成死循环
			
	3,在本类中调用本类其他属性或方法,此时可以忽略this不写

2.面向对象(封装、继承、多态)

1.封装

(1)优点

思想:包装

优点:
	1,美化
	2,降低耦合度
	3,保护内部
	4,方便使用

(2)Java代码中的封装

	变量:封装一个可以改变的数据
	数组:封装一组数据
	方法:封装一段代码
	类:封装多个属性与多个方法
	java文件:封装一个或多个类
	包:封装多个java文件
	项目:封装多个包
	...

(3)包

	本质:一个文件夹
	
	创建包:
		选择src文件夹,点击鼠标右键,选择new,选择package
		填写包名
		
	注意:
		包名使用全小写,不要用数字开头,不要出现特殊符号
		包名的命名潜规则:
			com.公司名称缩写.作用
			注意:.表示下一层文件夹
	
	关键字:package

	导包:
		关键字:import
		为什么要导包:
			所需使用的类与当前类不在同一个包中

(4)访问权限修饰符

	意思:限制属性,方法,构造函数,类等的使用范围
	
	分类:
		关键字				意义					使用范围
		public				公共的					当前项目中
		protected			受保护的					当前包中或继承关系中
		不写				默认的					当前包中
        private				私有的					当前类中
        
	总结:
	一般情况下:
		属性用private修饰,方法与类用public修饰
		属性用private修饰后需提供get与set方法

2.继承

(1)优点

概念:
	生活中的继承:晚辈获取长辈留下的财产与精神
	代码中的继承:
		多个类(B1,B2)抽取其共同点形成了一个类(A)
	注意:
		判断类A是否与类B有继承关系
		如果类B与类A存在继承关系,可以让类B继承与类A,此时类B将拥有类A的所有属性与方法,构造函数除外
		类B:称为子类
		类A:称为父类
		
优点:
	1,减少代码
	2,使代码结构清晰
	3,降低代码冗余度

总结:
	子类将拥有父类的所有属性与方法,构造函数除外(父类构造函数只能使用,不是拥有关系)

(2)继承的语法

语法:
	访问权限修饰符 class 子类名 extends 父类名{
		属性
		构造函数
		方法
	}	
注意:
		1,Java只能单继承
		2,如果一个类没有写继承,默认继承于Object
		3,如果父类中的方法与子类方法名相同,形参列表相同,返回值类型相同,访问权限修饰符子类大于或等于父类该方法,这种方法称为重写

(3)super的使用

	作用:子类中使用父类的内容

使用:
	属性
		特殊情况:子类的属性名与父类属性名相同,如何区分
		子类:this.属性名
		父类:super.属性名
	方法
		特殊情况:子类重写父类方法,在子类中使用该方法,如何区分是父类方法还是子类方法
		子类:this.方法名(实参列表);
		父类:super.方法名(实参列表);
	构造函数
		情况:创建子类对象时,需要给父类构造函数传值
		语法:
			super(实参列表);
		注意:
			1,要在子类构造函数第一行
			2,子类构造函数中如果没有调用父类构造函数,那么默认在其第一行有super();调用父类无参构造函数
			3,重写父类方法时,若访问权限修饰符比父类小,则会报错
	
总结:
	子类将拥有父类的所有属性与方法,构造函数除外

3.多态(事物 —— 事和物)

(1)概念

	一个 事物 的多种形态

(2)代码中的多态(事 —— 方法的重写与重载)

重写:
	要求:
		发生在继承关系中,子类访问权限修饰符大于或等于父类访问权限修饰符,返回值类型相同,方法名相同,形参列表相同,方法体不同
		
	注意:
		当某个对象重写了父类的方法,对象在调用方法名时,遵循就近原则,会调用子类重写后的方法;当子类未重写方法时,对象调用方法,其会调用父类的方法
		
重载:
	要求:
		发生在同一个类中,方法名相同,形参列表不同
		
		注意:
			当对象重写方法时,除了形参列表不同其余方法变量全部相同时,可以实现方法重载的效果,但此种方法的改变既不叫重写也不叫重载(不在同一个类中)

(3)代码中的多态(物 —— 对象)

(对象)
		如类A继承与类BA:子类
		类B:父类
		(父类对象可以看作是大数据类型,子类对象可以看作是小数据类型,其转换情况符合基本数据类型转换原则)
		
		类名A 对象名A = new 类名A();
		
		//子类对象转父类对象,可以自动转换
		类名B 对象名B = 对象名A;
		
		//父类对象转换子类对象,需要强制转换,有风险
		类名A 对象名A2 = (类名A) 对象名B; 

	注意:1,类的所有对象属于引用数据类型,其转换的实质是改变引用的指向
		  2,子类对象转换为父类对象会丢失自己特有的属性和方法
		  3.若一个类的本质不是父类,则此父类无法转化为其子类(编写程序不会报错,运行程序会报错)
		  4.重点:主要看一个类的本质是什么,使用 instanceof 可以某个对象是否的归属某个类的类型(父类或其他子类的类型)
		 		 eg:if (animal instanceof Dog)//对象animal是否属于Dog类

3.面向对象(三大修饰符)

1.抽象的

概念:无法描述的,无法实例的

关键字:abstract

可以修饰:
	方法
		语法格式:
			访问权限修饰符 abstract 返回值类型 方法名(形参列表);
		注意:
			1,抽象方法没有方法体
			2,有抽象方法的类一定是抽象类
			
	类
		语法格式:
			访问权限修饰 abstract class 类名{
				属性
				方法
				构造函数
			}
			
		注意:
			1,子类继承于抽象类,要么重写所有抽象方法,要么自己也是抽象类
			2,抽象类无法直接创建对象
			3,抽象类中不一定有抽象方法
			4,抽象方法一定在抽象类中

2.最终的

概念:不可修改的,最后的

关键字:final

修饰:
	类
		意义:最终类,不能被别的类继承
		语法:
			访问权限修饰符 final class 类名 extends 父类名{
				属性
				方法
				构造函数
			}
			
	方法
		意思:不可被重写
		语法:
			访问权限修饰符 final 返回值类型 方法名(形参列表){
				方法体
				return xxx;
			}
			
	属性
		意思:不可被修改,称为常量,常量命名全大写
		语法:
			访问权限修饰符 final 数据类型 属性名;
		final修饰的变量就是常量
		
	局部变量
		意思:不可被修改,称为常量,常量命名全大写
		语法:
			finl 数据类型 属性名;
		final修饰的变量就是常量

3.静态的

(1)基本概念语法

概念:该类所有对象共有的,属于类

关键字:static
	
修饰:

	属性:
		语法:访问权限修饰符 static 数据类型 属性名;
		static修饰的属性称为静态成员变量
		注意:
			1,static修饰的属性属于该类的所有对象,一个对象对其进行修改,所有对象的该属性都将被修改
			2,static修饰的属性多了一种调用方式
				语法:
					类名.属性名;
					类名.属性名 =;
				原来:
					对象名.属性名
					对象名.属性名 =;

	方法:
		语法:
			访问权限修饰符 static 返回值类型 方法名(形参列表){
				方法体
			}
		static修饰的方法称为静态方法
		注意:
			1,静态方法中只能 直接 使用静态成员(静态属性,静态方法)
			2,static修饰的方法多了一种调用方式
				语法:
					类名.方法名(实参列表);
				原来:
					对象名.方法名(实参列表);
			3,静态方法中不能使用thissuper(因为静态变量的声明周期长,其在类加载时创建,在没有对象存在时静态变量就已经存在,故不能在静态方法中调用非静态变量或方法)
			
	代码块:
		静态代码块

(2)static 关键字补充

static 关键字

​	1,静态变量或方法不属于对象,但要依赖于类,即属于类

​	2,静态变量是全局变量(生命周期从类被加载后一直到程序结束)

​	3,静态变量只存一份,在静态方法区中存储

​	4,静态变量是本类所有对象共享的一份,建议不要使用对象名去调用静态数据,直接使用类名调用

​	5,不能在静态方法中调用非静态变量或方法的原因:因为静态变量的声明周期长,其在类加载时创建,在没有对象存在时静态变量就已经存在,故不能在静态方法中调用非静态变量或方法

4.代码块

概念:一块代码

普通代码块:
	类中,方法以外
	
	语法:
			{
				代码
			}
		调用:
			每次调用该类构造函数创建对象时,由系统调用该类的普通代码块,在执行构造函数前调用

静态代码块:	
	与static结合使用

	语法:
		static{
		
		}
	调用:
		类加载时调用,所以只会调用一次
	
	类的加载时机:
		1,第一次创建该类对象时
		2,第一次创建子类对象时(先有父,后有子)
		3,使用类名调用本类静态属性(只有当JVM加载此类之后,才可以使用该类的静态属性)
		4,使用类名调用本类静态方法
		5,使用第一次使用反射获取该类对象时
			Class.forName("包名.类名");
			
	注意:
		1,类只加载一次
		2,一个类有静态与非静态属性,先加载静态属性

在继承关系:
	1,先加载父类静态,在加载子类静态,父类非静态,子类非静态
	2,在 1 条件下,属性 > 方法 > 静态代码块 > 代码块 >构造函数(静态 > 非静态)
	3,在使用new关键字调用构造函数创建对象时,先加载属性和方法,再执行构造函数的代码
	
;