【Java基础】面向对象


前言

学习面向对象的三大主线:
1.Java类及类的成员:属性、方法、构造器;代码块、内部类
2.面向对象的三大特性:封装、继承、多态
3.关键字:this、super、instanceof、static、final、abstract、interface、implements、package、import等。


一、面向对象说明、内存解析

面向对象说明

	面向对象:谁来做,将功能封装到对象,具备功能的对象
	
	核心概念:类和对象
			类:一类事物,比如抽象概念的人
			对象:一类事物的实例,实实在在的人
	
	重点:类的成员设计
			属性:成员变量
			行为:成员方法
	
	使用:
			1.创建类,设计类的成员
			2.创建类的对象
			3.调用:对象.属性、对象.方法

内存解析

对象内存解析:
				Person p1 = new Person();
				Person p2 = new Person();
				Person p3 = p1;
	//说明:
			1.new出来的每个对象都有独立的属性
			2.p3没有new 创建新的对象
			3.那么p3和p1共用同一个堆空间对象,即两个人数据相同
			4.无论修改p1,还是p3 ,它们的属性都会改变
			如:p3.age=1;那么p1.age 也等于1

	java内存解析:
			1.java源代码>编译>生成字节码文件.class>运行
			2.使用jvm类的加载器和解释器对生成的字节码文件进行解释运行
			3.即将字节码文件对应的类加载到内存,涉及到内存解析
			
			虚拟机栈:局部变量 ( = 左边变量名)
			堆:右边 new 的对象及属性
			方法区:类的加载信息 main方法、常量池、静态域

在这里插入图片描述

二、属性和方法

属性

	属性(成员变量)VS 局部变量
		相同点:
				1.定义格式:数据类型 变量名
				2.先声明,后使用
				3.都有对应的作用域
		不同点:
				1.声明位置不同
					成员变量:类中
					局部变量:方法、构造器、代码块、形参
					
				2.权限修饰不同
					成员变量:可以使用权限修饰符
					局部变量:不可以
					
				3.默认初始化不同
					成员变量:都有初始化值
					局部变量:没有初始化值,调用时需赋值

				4.内存中加载位置不同
					成员变量:加载到堆中
					局部变量:加载到栈中

方法

	声明:权限修饰符 返回值类型 方法名(形参){方法体}
		注:static、final、abstract 都可修饰方法
		
		权限修饰符:private、public、protected、default

		返回值:void(无返回值)、其它数据类型(有返回值,需要return)
					return关键字:
						使用范围:方法体中
						作用:1.结束方法 2.针对有返回值的方法,用return返回所需数据
		形参:可有可无			

	注:
		1.方法使用中,可以调用当前类的属性和方法
		2.特殊:方法调用其本身,被称为递归方法
		3.方法中不能定义方法

三、匿名对象 和 方法重载

匿名对象

	匿名对象:只能调用一次,一般作为参数使用
	比如:void 方法名(Phone phone),调用此方法时可写成 ph.方法名(new phone())
	比如:new phone().方法名() // 使用后此对象就被释放

	抽象类的匿名子类、匿名对象:(这里很绕,建议先看 十五章abstract抽象关键字)
		匿名子类的非匿名对象:
			Person person = new Person(){子类重写父类方法};
				// Person person :代表非匿名对象
				// new Person():代表 匿名
				//{子类重写父类方法}:代表子类

	匿名子类的匿名对象:
		new Person(){子类重写父类方法}
				// 对比 匿名子类的非匿名对象			

方法重载

	说明:同一个类中,定义一个以上的同名方法,但它们的形参不同
	
	判断是否属于重载:跟权限修饰符、返回值类型、形参变量名、方法体无关
		即就算它们不同,只要方法名相同,参数列表的类型、数量相同,就是重载

	调用重载方法:根据参数列表调用

四、方法参数的值传递机制、可变个数形参

方法参数的值传递机制

	参数种类:
			形参:方法声明时的参数
			实参:调用方法时,实际传给形参的参数值

	java中的实参如何传递给方法?
			java中的参数传递机制只有一个:值传递
			即将实参的副本传给方法,参数本身不受影响

	形参是基本数据类型:将实参的值     传递给形参
	形参是引用数据类型:将实参的地址值  传递给形参

可变个数的形参:数据类型…变量名

	说明:
			1.当调用可变个数形参的方法时,传入的参数可以是任意个数
			2.必须声明在形参的最后一个
			3.只能声明一个
			4.本质是数组
public void show(String ... strs){
    system.out.println("show(String...strs)")
    for(int i=0;i<strs.length;i++>){
        system.out.println(strs[i])    
    }
}
//调用
test.show(new String[]{"AA","BB"})

--------------------------------------------------------

五、封装

	设计思想:隐藏内部的复杂性,只对外开放简单的接口,从而提高代码的可扩展、维护性

	使用: 
			private int age;
			public  int  getAge(){return age;}
			public void  setAge(int age){this.age=age;}

	设计追求:高内聚,低耦合
		高内聚:类的内部数据操作细节字节完成,不允许外界干涉
		低耦合:仅对外暴露少量的方法用于使用,或者说是低依赖性

	封装体现:需要权限修饰符,将类的属性私有化,提供get/set,设置获取属性的值

六、构造器

	作用:创建对象、初始化对象属性
	
	格式:
		public 类名(形参){ }
	
	说明:
		1.任何一个类都有构造器
		2.系统会默认送一个空的构造器,如果自己写了,系统就不送了
		3.一个类可以有很多构造器:重载即可
		4.一个类至少有一个构造器

七、权限修饰符 和 this、package、import关键字

权限修饰符

	四种(范围从小到大排序):private、缺省default、protected、public
	
	用途:修饰类、属性、方法、构造器、内部类

	注:修饰类,只能使用 public 或 default

this、package、import关键字

	this 说明:
				1.可以修饰:属性、方法、构造器
				2.修饰属性和方法:代表当前对象  / 正在创造的对象 / 调用它的对象
				3.一般形参和属性名同名时使用,其它情况可省略不写this
				4.使用this调用构造器:
					当构造器中有重复代码,可以使用this() 或 this(形参) 来调用指定构造器
					注:必须声明在首行,且只能声明一个,不能调用自己

	package 说明:
				1.声明类和接口所在的包,声明在源文件首行
				2.包名全小写,每.一次,代表一层目录
				3.同一个包下,不能命名重名

	import 说明:导入包,自动导入

----------------------------------------------------

八、继承:extends

	格式:public class 子类名 extends 父类名{}
	
	继承体现:
			1.继承父类中的属性和方法
			2.子类可以声明自己特有方法
			
	继承优点:
			1.减少代码冗余,提高代码复用性
			2.便于扩展功能
			3.为多态使用,提供前提
			
	注:java只支持单继承和多层继承,不支持多继承
			1.一个子类只能有一个父类,一个父类可以有很多子类
			2.有直接继承(直接父类)、间接继承(间接父类)
			3.子类继承所有父类的属性和方法
					>所有父类:直接父类+间接父类
					>间接父类:父类的父类
			4.Object类 是所有类的父类

九、重写

	说明:子类继承父类后,在子类中对父类的同名同参方法进行重写覆盖
		>重写后,子类对象调用父类中的同名同参方法时,实际执行的是子类中重写后的方法

	规定: 重写方法(子类中的方法)、被重写方法(父类中的方法)
	
		1.子类重写父类方法,要求方法名和参数相同
		
		2.子类重写的方法 权限修饰符,范围不能小于父类被重写的方法
			>注:子类不能重写父类的private方法
		
		3.返回值类型:
			>父类是void,子类必须是void
			>父类的返回值是A类型,子类的返回值可以是A类型,也可以是A类型的子类
			>父类是基本数据类型,子类必须是基本数据类型
	
		4.子类抛出的异常类型,不大于父类被重写方法的异常类型
		
		5.子类和父类中同名同参方法要么都声明为 非static ,要么都声明static
			>注:声明static 不叫重写,且父类的static方法,一定不能被重写

十、super关键字 和 子类对象实例化过程

super关键字

	说明:
			1.super:父类的...
			2.可以调用父类的属性、方法 : super.属性/方法
			3.调用父类的构造器: super();

	何时使用:
			1.属性名相同,但意思不同
			2.方法被重写时,需要用到父类的方法体
			3.在构造器中,super()和this(),只能二选一,如果不选,默认 super()

子类对象实例化过程

	说明:
		1.子类继承父类后,就获取了父类的属性和方法
			创建子类对象,在堆空间,就会加载所有父类中声明的属性
		
		2.子类通过构造器创建对象时,一定会直接或间接的调用其所有父类的构造器,直到Object类空参构造
		
		3.正因为加载了所有父类结构,才可以看到内存中所有父类中的结构,子类对象才可以考虑调用

	注:子类创建对象时,虽然调用了所有父类的构造器,但它只创建一个对象,就是子类的对象

--------------------------------------------

十一、多态 和 instanceof关键字

多态

	格式:父类 对象名 = new 子类();

	使用说明:虚拟方法调用
			1.子类中定义了和父类同名同参的方法,在多态情况下,父类方法就叫虚拟方法
			2.父类根据不同的子类对象,动态调用属于子类的该方法
			注:多态在编译时只能调用父类中声明的方法,运行时调用的是子类中重写的方法
	
	总结:编译看左,运行看右
		>如果它不是晚绑定,它就不是多态
		>方法调用那一刻,解释运行器才会确定自己所要调用的具体方法

	多态使用前提:1.继承关系 2.方法重写

	为什么使用多态:没有多态性,抽象,接口就没有意义

	多态性好处:使用一个父类,就可以调用子类,如果子类很多,用多态就很方便
	
	注:多态不适用属性,只适用于方法

	注:
		1.多态只能调用父类有的方法
		2.如果想调用子类特有的方法,需要转换为子类对象
		3.这时需要用到instanceof关键字

instanceof关键字

	说明:多态不能调用子类特有的方法

	如何才能调用子类特有的方法?
		使用强制类型转换,向下转型 :Man man = (Man)person;
		
	注:使用强转时,可能会出现类型转换异常,为了避免这个问题,需要使用 instanceof关键字
	
	使用instanceof关键字:
		格式:父类多态对象 instanceof 子类 (父类多态对象 是否是 子类的实例),是就向下转型
		比如:if(person  instanceof Man)
					Man man = (Man)person;
								man.特有方法();

十二、Object类 和 包装类

Object类

	说明:java中所有类的根父类,没有继承关系的类,默认父类就是Object类
		
		1.Object类中只声明了一个空参构造器
	
		2.方法:
				(1)notify()、notifyAll()、wait() 线程通信
				(2)hashCode() 集合哈希值
				(3)finalize():垃圾回收
				(4)getClass():获取当前对象的所属类
				(5)equals():比较两个对象是否相等,可以重写:比较对象实体
				(6)toString():获取内存地址值,可以重写:返回实体内容

包装类

		基本数据类型>引用数据类型:包装类
		把基本数据类型封装,变成对象,就叫包装类

		8种基本数据类型:除 int>Integer ,char>character ,其余6种,首字母大写
		除char、boolean,其余6种父类都是Number

		注:包装类是对象,不能进行加减乘除运算,且默认值都是 Null

		基本数据、包装类 和 String 之间相互转换:
				~~1.基本数据类型>包装类~~ 
					~~包装类 i = new 包装类(变量);~~ 
				
				~~2.包装类>基本数据类型~~ 
					  ~~调用包装类的:类型Value()~~ 

				3.基本数据类型、包装类 > Stirng
					(1)Stirng str =  变量 + " ";
					(2)String.ValueOf(包装类/基本数据类)

				4.String >基本数据类型、包装类
					包装类.parseXxx(str);
						>Xxx:包装类的基本数据类型

		jdk5.0新特性:自动装箱和拆箱
			即不需要手动 基本数据类型和包装类转换了
			自动装箱:基本>包装
				int  num = 10 ; Integer i = num;
			自动拆箱:包装>基本
				int b =  i;

十三、static关键字 和 final关键字

static关键字

	 说明:
	 		1.修饰:属性、方法、代码块、内部类
	 		2.修饰属性:静态变量(类变量)
	 			注:属性按是否被static修饰,分为静态变量、非静态变量(实例变量)
	 				静态变量:共享变量,修改会影响其它对象的静态变量;
	 				实例变量:每个对象都有自己的值,修改不影响其它对象
					
				>静态变量随着类的加载而加载,可通过 “类.属性” 直接使用
				>静态变量的加载早于对象的创建
				>静态变量归类所有
				>只加载一次,静态变量也只存在一份,存在于方法区静态域

			3.修饰方法:静态方法
				>随着类的加载而加载,可通过 “类.方法”直接使用
				>静态方法中,只能调用静态方法、属性
					非静态方法,都可以调用
				>静态方法中,不可使用 this、super关键字
					因为静态方法早于它们加载,调不动
			
		开发中如何确定一个“属性”要不要使用 static关键字:
				>属性共有,比如国家
				>类中常量 也可以声明static

		开发中如何确定一个“方法”要不要使用 static关键字:
				>操作静态属性方法
				>工具类中的方法

final关键字

	说明:
			1.修饰:变量、方法、类
			2.修饰变量:常量
					>修饰属性:可以考虑赋值位置:显式、代码块、构造器
					>修饰局部变量:常量,不能被重新赋值

			3.修饰方法:不能被重写
			4.修饰类:不能被继承

			static final:
					>修饰属性:全局常量
					>修饰方法:直接通过类调用,不能被重写(注:通常不用)

十四、代码块、内部类

代码块

	格式:{ }
	作用:初始化类、对象
	说明:
			1.内部可以有输出语句
			1.代码块分为静态代码块、非静态代码块
				(1)静态代码块 static{ }
						>随着类的加载而加载执行,只加载执行一次
						>作用:初始化类的信息
						>定义多个静态代码块,先后顺序执行
						>静态代码块执行,优先于非静态代码块
						>静态代码块只能调用静态方法
				
				(2)非静态代码块
						>随着对象创建而加载执行
						>每创建一个对象,就执行一次
						>作用:初始化对象属性
					
	注:代码块只能被 static 修饰

内部类

	说明:
			1.一个类定义在另一个类中,前者“内部类”,后者“内部类”
			2.分类:
				>成员内部类:静态、非静态
				>局部内部类:方法、代码块、构造器内

		成员内部类:
				1.可以调用外部类结构,比如方法、属性等
				2.可以用staic修饰,修饰后就是静态
				3.可以被4种权限修饰符修饰
				4.可以定义属性、方法、构造器
				5、可以被final修饰,修饰后不能被继承
				6.可以被abstract修饰,修饰后不能实例化

		实例化成员内部类:
				>静态成员内部类(可以直接被调用)
						外部类.内部类 对象名 = new 外部类.内部类();
				>非静态成员内部类:
						1.先创建外部类对象
						2.外部类.内部类 对象名 =外部类对象.new 内部类();

		区分内部类调用外部类结构:
				>区分同名属性
						外部类属性:外部类.this.属性
						内部类属性:this.属性

			这里有点绕,自行体会

		注:局部内部类开发中很少见

--------------------------------------------------------------

十五、abstract 和 接口 interface implements关键字

abstract关键字:

	说明:
			1.修饰:类、方法
			2.修饰类:抽象类
				>不能创造对象
				>一定有构造器,便于子类实例化
				>开发中,抽象类一定有子类
			
			3.修饰方法:抽象方法
				>没有方法体
				>一定在抽象类中
				>由子类重写其方法
	注:
			1.abstract 只能修饰类和方法
			2.不能修饰 private私有,static静态、final  方法和类

	抽象类的体现及应用:模版方法设计模式
			抽象类作为多个子类的通用模版,子类可以扩展,并保留父类抽象类的属性行为

		解决问题:
			开发功能有一部分是固定,有一部分不确定
			固定的交给父类抽象类,不确定的交给子类

接口 interface implements关键字

	说明:
			1.interface:代表接口
			2.implements:代表 实现接口 ,实现接口的类被称为实现类

	interface 使用:public interface 类名{} //类名即接口名
	implements 使用: public class 类名 implements 接口名{}

	注:
		1.实现多个接口,且接口之间有相同方法,或者和父类有相同方法,会冲突,必须重写
		2.接口不能有构造器,不可以实例化
		3.实现类没有重写接口所有抽象方法,那么实现类依旧是抽象类
		4.实现类可以实现多个接口
		5.接口之间可以多继承
		6.接口具体使用:必须体现多态性
			如: UserDao userDao = new UserDaoImpl();
					//UserDao是接口,UserDaoImpl是UserDao的实现类;

	接口的体现及应用:代理模式
		结构:接口、被代理实现类、代理实现类
					代理实现类:
							1.私有接口的对象
							2.带参构造器
							3.方法中调用对象的方法
							4.main方法中,创建代理带参对象

		代理分类:静态代理、动态代理
		应用场景:安全代理、远程代理、延迟加载

main方法

	说明:
			1.一个程序的入口
			2.也可以当做一个普通的静态方法
			3.作为与控制台交互的方式(比如 Scanner 输入)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值