OPP面向对象

面向对象的思想

1.概述

  • 面向对象是基于面向过程的思想
二者区别在于处理问题的方式不同
面向过程:将解决问题的过程拆成方法,执行每个方法解决问题
面向对象:强调的是对象,然后由对象去调用功能

2.思想特点

  • 更符合我们思想习惯的思想
  • 复杂的事情简单化
  • 将我们从执行者变为了指挥者
  • 举例:
我让同学带饭
我只需要等饭(面向对象)
怎么买饭就是同学的事情(面向过程)

3.面向对象开发

  • 不断地创建对象,使用对象,指挥对象做事情

4.面向对象设计

  • 管理和维护对象间的关系

5.面向对象三大特征

  • 封装(encapsulation)
将对象的状态信息隐藏于对象内部,不允许外部对象直接访问对象内部信息
  • 继承(inherritance)
子类拥有父类所以属性和方法,但对于私有方法只是拥有,不能访问
  • 多态(polymorphism)
父类引用指向父类对象,若子类重写父类方法则使用子,否则使用父

对象

1.概念

  • 该类事物的具体表现形式,具体存在的个体
  • 比如:麻雀
  • 万物皆对象

2.创建对象格式

类名 对象名 = new 类名/构造函数名();
  • 实例化(创建对象时)时会初始化类的成员,如果没有赋值会初始化为该数据类型的默认值
  • 一个引用指向0个或1个实例,一个实例可以有多个引用
  • 创建对象语句图解
    在这里插入图片描述

3.内存图解

4.匿名对象

  • 概述:没有名字的对象,是一种简单化表现形式
  • 格式:new 类名(…);
  • 应用场景
1.调用类中方法且仅调用一次,调用多次时不合适
	new 类名().类中方法名();
2.可作为实际参数传递  
	对象名.对象中的方法(new 类名());
  • 优点:调用完毕就是垃圾,可以被垃圾回收器回收

5.对象相等与引用相等的区别

  • 对象相等:内存中的内容相等
  • 引用相等:内存地址相等

1.概述

  • Java语言中最基本的单位:类
  • 一组相关的属性和行为的集合,是一个抽象概念
属性:该事物的描述信息————成员变量
行为:该事物能够做什么————成员方法
  • 比如:鸟类(而不是XX鸟)

2.成员变量

  • 使用格式:对象名.变量名
  • 注意事项
1.在自己定义的类中局部变量名称可以和成员变量名称一样,在方法中使用的时候
		采用**就近原则**
  • 成员变量与局部变量的区别
1.在类中位置不同
	成员变量:在类方法外
	局部变量:在方法定义中或在方法声明上
2.在内存中位置不同
	成员变量:在堆内存
	局部变量:在栈内存
3.生命周期不同
	成员变量:随着对象的创建而存在,随着对象的消失而消失
	局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
4.初始化值不同
	成员变量:有默认初始值
	局部变量:没有默认初始值,必须定义,赋值后才可以使用

3.封装 private

  • 只能在本类中访问,外界不可以直接访问
  • 概述:隐藏对象的属性和实现细节,仅对外提供公共访问方式
  • 优点
1.隐藏实现细节,提供公共的访问方式
2.提高了代码的复用性 
3.提高了安全性
  • 实现原则
1.将不需要对外提供的内容都封装隐藏起来
2.将属性隐藏,提供公共方式对其访问

建议:属性私有化,方法公有
  • 关键字 private
概述:
	是一个限权修饰符
	可以修饰成员(成员变量和成员方法)
	被其修饰的成员只能在本类中才能访问

常见应用:
	将所有的成员变量用private修饰
	提供对应的getXXX/setXXX方法(获取值/赋值)

4.关键字 this

  • this代表所在类的对象引用,简单记this就代表当前类的一个对象——被哪个对象调用,this就代表那个对象
  • 使用场景:局部变量隐藏成员变量
  • 作用
在成员方法中,this.变量名
	可用于访问成员变量

若没有this关键字,就近原则
  • 私有类间接访问规范
赋值:setXXX();
		private String sex;
		public void setSex(String sex){
			this.sex = sex;
		}
取值:getXXX();
		private String sex;
		public String getSex(){
			return sex;
		}

5.构造方法 constructor

  • 概述
给对象的数据进行初始化===set方法一样用于赋值
	**最佳实践:提供一个无参和带所有参数的构造函数 其他结合setter方法
  • 格式
1.方法名与类同名
2.无返回值类型,连void都没有
3.没有具体返回值

public 类名(...){...}
	---> (...)中可以有参可以无参

在这里插入图片描述

  • 注意事项
1.若不提供构造方法,系统会默认给出无参构造函数
2.若提供了构造方法,系统将不再提供无参构造函数
3.构造方法可以重载,但不能重写
  • 创建对象(new)的时候自动调用构造函数
类名 变量名 = new 类名(.......中无参即调用无参构造方法
	....中有参即调用有参构造方法

6.成员方法

  • 使用格式:对象名.方法名(…)
  • 形参与返回值问题
XXX做形参
	1.基本类型:形参的改变不影响实参
	2.引用类型:形参的改变直接影响实参(因为实际上改变的是地址值)
		类名:需要该类的对象
		抽象类名:需要该类子类对象
		接口名:需要该接口的实现类对象

返回值类型
	1.基本类型:形参的改变不影响实参
	2.引用类型
	 	类:返回的是该类的对象
		抽象类:返回的是该类的子类对象
		接口:返回的是该接口的实现类对象
  • 链式编程
对象.方法1(). 方法2().......方法n()
	方法1调用完毕后返回一个对象
	方法2调用完毕后返回一个对象
	方法n调用完毕后返回可能是对象,也可以不是

7.关键字 static

  • 访问格式:类名.static变量/方法名
  • 特点
1.被类的所有对象共享**
2.静态变量随着类的加载而加载,随着类的消失而消失
3.优先于对象存在,生命周期伴随整个程序
4.通过类名调用(推荐),也可以通过对象名调用
  • 内存图解
    在这里插入图片描述
  • 注意事项
1.在静态方法中没有this关键字**
	静态是随着类的加载而加载
	this是随着对象的创建而存在
	静态比对象先存在
2.静态方法只可以访问静态的成员变量和静态的成员方法
	因为非静态成员不存在时静态方法就已经存在,访问不存在的成员属于非法调用
3.非静态方法可以访问所有成员(包括静态与非静态) 但不可以定义静态局部变量
4.main是一个静态的,它访问
	静态方法时
		格式:方法名(....)
	非静态方法时
		格式:类名 对象名 = new 类名(....)
			  对象名.方法名(....5.程序运行的时候static修饰的就被加载,而不被修饰的要创建对象(new)时才会加载(即分配内存空间)
6.非静态成员的生存期决定于该类的生存期,而静态成员生存期则与程序生命期相同
  • 静态变量与成员变量的区别
1.所属不同
	静态变量属于类,所以也称为类变量
	成员变量属于对象,所以也称为对象变量
2.内存中位置不同
	静态变量储存于方法区的静态区
	成员变量储存于堆内存
3.生命周期不同
	静态变量随着类的加载而加载,随着类的消失而消失
	成员变量随着对象的创建而存在,随着对象的消失而消失
4.调用不同
	静态变量可以通过类名调用,也可以通过对象调用
	成员变量只能通过对象名调用
5.访问限制不同
	静访静,非静访所以

8.main方法的格式讲解

public static void main(String[]args)
  • public:公共的
访问权限最大
由于main方法是被jvm调用,所以权限要够大
  • static:静态的
不需要创建对象,通过类名就可以
方便jvm的调用
  • void
方法的返回值给调用者,而main方法是被jvm调用,所以返回内容给jvm没有意义
  • main:常见的方法入口
  • String[] args:字符串数组
早期为了接收键盘录入数据
控制台输入  java 类名 a1 a2..(args内容)

9.代码块

  • 概念:代码块用{}括起来
  • 局部代码块
位置:局部位置(方法中)
作用:限定变量的生命周期,及时释放提高内存利用率
  • 构造代码块
位置:类中的成员位置,用{}括起来的代码
	每次调用构造方法执行前都会先执行构造代码块**
作用:将多个构造方法中的共同代码放在一起,对对象进行初始化
  • 静态代码块
位置:类中的成员位置,用{}括起来的代码,但是用static修饰
	只执行一次**
作用:对类进行初始化
  • 执行顺序
先执行静态代码块(只执行一次)
再执行构造代码块(每次调用构造方法都执行)
最后执行构造方法

与语句放置的顺序无关

10.继承 extends

  • 使用场景
1.多类中存在相同属性和行为时,可将这些属性放在一个单独类中,只需继承此类即可使用(代码重用)
2.继承实际体现的是一种“is a”的关系
3.采用假设法:如果有两个类A,B,只要符合AB的一种或者BA的一种即可以考虑使用继承
  • 格式
class 子类名 extends 父类名{}

父类:基类或者超类
子类:派生类
  • 好处
1.提高了代码的复用性,同一功能放于同一类中
2.提高了代码的维护性,出问题修改一处即可
3.让类与类产生了关系,是多态的前提
  • 坏处
1.让类与类产生了关系,使类的耦合性增强,增加后期维护的难度
	开发原则:低耦合,高内聚
		耦合:类与类的关系
		内聚:自己完成某件事的能力
2.打破封装性
  • 特点
1.只支持单继承(C++支持多继承)
	class 子类名 extends 父类名1,父类名2{}====不支持
	一个儿子一个爹,但爹可以有多个儿子
2.支持多层继承
	class A{}
	class B extends A{}
	class C extends B{}
	继承只是单方向的 子可访问父  父不可访问子
  • 注意事项
1.子类只能继承父类所有的非私有的属性和方法
2.子类不能继承访问父类的构造方法,但可以通过super关键字访问
3.不要为了两个类中的部分功能而去使用继承
4,当创建子类对象时,先创建父类对象,再完成创建子类对象,若父类对象创建失败,则无法创建子类对象
5.当创建子类对象时,先完成父类中成员初始化,再调用父类构造函数,再完成子类初始化,再调用子类构造函数
6.每个子类构造函数都默认先调用父类 无参 构造函数
  • 继承中成员变量的关系
1.子类中的成员变量名与父类中的成员变量名不一样
2.子类中的成员变量名与父类中的成员变量名一样,**就近原则**
	子类方法的局部范围找,有就使用
    子类成员范围找,有就使用
    父类成员范围找,有就使用
    都没有就报错
3.子类中的局部变量,成员变量及父类中的成员变量的变量名相同
	输出本类局部变量(局部方法):变量名(方法名)
	输出本类成员变量(本类成员方法):this.变量名(本类成员方法)
	输出父类成员变量(父类成员方法):super.变量名(父类成员方法)
  • 继承中构造方法的关系
1.子类的每一个构造方法的第一条语句默认都是super(),super关键字,子类所有构造方法也默认先访问父类中的无参构造方法,访问完后再执行自己的构造方法 ,为子类访问父类数据初始化
	注意:用了super就不要再使用this
2.若父类中没有无参构造方法,子类中的构造方法会报错,怎么解决?
	方法1:在父类中加一个无参构造方法
	方法2:通过super关键字访问父类的有参构造方法
	方法3:子类通过this去调用本类的构造方法
3.this()super()必须出现在第一条语句上,且不能同时出现,否则就会出现父类数据多次初始化
	注意:子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
	
4.类的初始化过程
	成员变量初始化(默认值初始化->显示值初始化)
		->构造方法初始化
5.父类初始化->子类初始化
6.静态代码块父->静态代码块子->构造代码块父->构造方法父->构造代码块子->构造方法子

11.关键字 super

  • 作用
指向当前对象的父类,可以操作父类的成员,调用父类构造函数
  • 格式
super(参数列表)
	只能放在子类构造函数的第一行使用
super.成员变量
  • 用了super就不要再使用this

12.重载 overload

  • 相同点
1.方法实现功能相同
2.方法名相同
  • 不同点
1.参数类型不同
2.参数数量不同
3.参数类型顺序不同
	注意:与 参数名 顺序无关
  • 特点
1.与方法返回值无关
2.作用在同一作用域  =  发生在同一个类内部
3.当遇到重载函数的时候,编译器如何根据参数选择?(取决于编译器)
	答:完全匹配+类型提升
4.构造方法可以重载,静态方法也可以重载

13.重写 override

  • 概述:子类和父类中出现了一模一样的方法声明
  • 应用:当子类需要父类功能,而功能主体子类有自己特有的内容时
  • 注意事项
1.父类中的私有方法不能被重写(父类私有方法子类根本就无法继承)
2.父类静态方法子类也必须通过静态方法进行重写
3.子类重写父类方法时最好声明一模一样
  • 特点
1.两同:方法名、形参列表相同
2.两小:返回值类型、抛出异常更小
3.一大:访问修饰符

14.关键字 final

  • 概述
修饰类,方法和变量
  • 特点
1.修饰类:该类不能被继承
2.修饰方法:该方法不能被重写
3.修饰变量:该变量不能被重新赋值==常量
  • 注意
final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销
final关键字提高了性能,JVM和Java应用都会缓存final变量
使用final关键字,JVM会对方法、变量及类进行优化
  • 思考题
    在这里插入图片描述

15.多态

  • 概述:同一对象在不同时刻表现出的不同状态,同一引用名创建不同对象
  • 格式
父类名 对象名 = new 子类名()
  • 前提
1.有继承extends或实现接口关系
2.有方法重写
3.有父类或父接口引用指向子类对象 fu f = new zi();
  • 成员访问特点
1.成员变量:
	编译看左边(f),运行看左边(f)
2.构造方法:
	构造子类对象时,先访问父类的构造方法,对父类的数据进行初始化
3.成员方法:
	编译看左边(f),运行看右边(z)(成员方法存在方法重写所以看右边)
4.静态方法:
	编译看左边(f),运行看左边(f)(静态与类相关算不上重写所以还是访问左边)
  • 分类
具体类多态
	class Fu{}
	class Zi extends Fu{}
	Fu f = new Zi();
抽向类多态(常用)
	abstract class Fu{}
	class Zi extends Fu{}
	Fu f = new Zi();
接口多态(最常用)
	interface class Fu{} 
	class Zi implements Fu{} 
	Fu f = new Zi();
  • 种类
静态多态:重载
	1.在编译时决定调用哪个方法——编译时报错
	2.重载是否发生与继承没有必然联系
动态多态:重写
	1.在运行时决定调用哪个方法——运行时抛出异常
	
动态多态实现前提:继承,重写,必须由基类引用指向派生类对象,且通过基类的引用调用被覆盖的方法
  • 优点
1.提高了代码的维护性(继承保证)
2.提高了代码的扩展性
	一种函数多种形态,调用同一个函数得到不同结果
  • 弊端
不能使用子类中特有的方法,只能使用重写方法
解决方法
	1.创建子类对象调用方法zi z = new zi()
	2.(推荐)向下转型**:将父类的引用强制转换为子类的引用
  • 多态内存图解在这里插入图片描述

16.转型

  • 向上转型
父类名 dx=new 子类名()
父类引用 = 子类对象

只能调用子类重写方法,不能调用子类特有的
	且调用自己的成员变量
		若方法没有被重写,则调用父类自己的成员方法
  • 向下转型(强转)
Parent p = new Son()
Son s = (Son)p;
Son p = (Son) new Parent();===不行
  • 强转内存图解
    在这里插入图片描述

17.抽象 abstract

  • 抽象方法
格式:权限修饰符 abstract 返回值 方法名(形参列表)
使用:某方法没有必要实现,但又不可少
  • 抽象类
1.概述:不是具体的功能称为抽象功能,而一个类中有抽象的功能该类必须是抽象类
2.格式:abstract class 类名{}
3.注意
	抽象类中不一定有抽象方法,但有抽象方法的类必须定义为抽象类
	抽象类有构造方法,但只能用于继承,不能实例化(new),构造方法用于子类访问父类数据的初始化
	抽象类派生出的子类必须提供抽象类所有的抽象方法的具体实现,若没有全部实现抽象方法,则该子类也必须定义为抽象类
4.抽象类的成员特点
	成员变量:既可以是变量也可以是常量
	构造方法:用于子类访问父类数据的初始化
	成员方法:可以是抽象的也可以是非抽象的
5.抽象类中不能有的关键字
	private 冲突——导致不能重写
	final 冲突——导致不能重写
	static 无意义
6.抽象类中没有抽象方法也可以定义为抽象类,有什么用?
	为了不让创建对象
  • abstract只能修饰方法和类

18.接口 interface-implement

  • 概述:接口不是实际意义上的类,仅仅表示功能的扩展
  • 接口类interface
格式:
	权限修饰符 interface 接口名{
		定义方法中可以省略abstract关键字
	}
	类中所有方法都是抽象方法,没有方法体	
	接口名建议I开头

特点
	1.接口是一种抽象的类型,不能被实例化,按照多态的方式实例化
	2.不能有main方法

接口子类
	可以是抽象类,但意义不大
	可以是具体类,要重写接口中所有的抽象方法

接口成员
	1.成员变量
		只能是常量,并且是静态的
		默认修饰符:public static final
	2.构造方法:接口没有构造方法
	3.成员方法
		只能是抽象的
		默认修饰符:public abstract
  • 接口实现类implement
格式:class 实现类 implements 接口{}
  • 特点
1.一个实现类可以实现多个接口
	class 实现类 implements 接口1,接口2{}
2.继承父类的同时可以实现接口
	class 子类 extends 父类 implements 接口{}

19.类-接口关系与区别

  • 类与类的关系
依赖(使用)  use a
	public void show( Parent p){}
组合(包含)  has a
	一个类中包含另一个类
继承关系(父子)  is a
	只能单继承,可以多层继承
  • 类与接口的关系
实现关系
	可以单继承,可以多继承,还可以在继承一个类的同时实现多个接口
  • 接口与接口的关系
继承关系
	可以单继承,可以多继承
  • 抽象类与接口的区别
1.成员区别
	抽象类
		成员变量:可以变量也可以常量
		构造方法:有
		成员方法:可以抽象也可以非抽象
	接口
		成员变量:只可以是常量
		构造方法:无
		成员方法:只可以是抽象
2.关系区别
	类与类:继承,单继承
	类与接口:实现,单实现,多实现
	接口与接口:继承,单继承,多继承
3.设计理念区别
	抽象类:被继承体现的是is a的关系,抽象类中定义的是共性功能
	接口:被实现体现的是like a的关系,接口中定义的是扩展功能

20.类中类对象的赋值

  • 方法一:在类1中成员变量的位置创建类2对象,在测试类3中创建类1对象后,测试类3中
赋值语句:类1对象.2对象.2成员变量 = XXXX;
  • 方法二:在测试类3中创建类2对象并赋值,再创建类1对象后,测试类3中
赋值语句:类1对象.2对象 =3中类2对象

内部类

1.作用

  • 对类进行分类管理
按功能分
按模块分
  • 把相同的类名放在不同的包中

2.格式

  • package 包名;(多级包用.分开)

3.包名

  • com.公司名.项目名

4.注意事项

  • package语句必须是程序的第一条可执行代码
  • package语句在一个Java文件中只能有一个
  • 如果没有package默认表示无包名

5.带包的编译运行

  • 手动式
编写一个带包的Java文件
通过Javac命令编译该Java文件
手动创建包名
把第二步的class文件放到第三步的最底层包
回到和根目录在同一目录的地方
然后运行
  • 自动式
编写一个带包的Java文件 
javac编译时带上-d .即可
javac -d . xxx.java

6.导包

  • 使用背景:多次使用一个带包的类,非常麻烦,所以导包import
  • 格式: import 包名…类名
  • 注意:此方式导入的是类的名称,用谁就导谁

7.不同包下同名类的访问

  • case01下的Person类
import com.yc.oop2.case01.Person;     
Person p = new Person();
  • case02下的Person类
包的全路径.类名   
com.yc.oop2.case02.Person p1 = new com.yc.oop2.case02.Person();

8.package import class顺序关系

  • package>import>class
package:只能有一个
import:可以有多个
class:可以有多个,建议是一个

修饰符总结

1.权限修饰符

  • private——只有本类可以用
  • 默认
  • protected
  • public
  • 访问情况
> 在本类中四种都可以访问
> 同一包下(子类和无关类)除私有的都可以访问 	
> 不同包下(子类)protectedpublic可以访问
> 不同包下(无关类)public可以访问
  • 这四种修饰符在任意时刻只能出现一种

2.状态修饰符

  • static 修饰内部类,方法,字段
  • final 修饰类、字段、方法

3.抽象修饰符

  • abstract 修饰类和方法

4.修饰符的使用

默认修饰符:class 类名{}
public修饰符:public 类名{}===(用的最多)
final修饰符:public final class 类名{}
abstract修饰符
  • 成员变量
private修饰符:private int x =10;    (用的最多)
默认修饰符:int x = 10;
protected修饰符:protected int x = 10;
public修饰符:public int x = 10;
static修饰符:public static int x = 10;
final修饰符:public final int x = 10;
static+final修饰符:public static final int x = 10;
  • 构造方法
private修饰符:private 类名(...){...}
默认修饰符:类名(...){...}
protected修饰符:protected 类名(...){...}
public修饰符:public 类名(...){...}    (用的最多)
  • 成员方法
所有的修饰符都可以(用最多的是public

基本类的标准代码写法

1.类

  • 成员变量
  • 成员方法
getXXX()
setXXX()
  • 构造方法
带所有参
无参

2.给成员变量赋值的方法

  • 无参构造方法+setXXX() ==== 开发中常用(灵活性高)
  • 有参构造方法

3.输出成员变量值的方式

  • 通过getXXX()分别获取然后拼接
  • 通过调用该类中函数搞定

基本概念

  • 复合数据类型是通过类或者接口
  • 虚函数即没有final关键字的函数
  • 实例方法即非静态方法
意思就是他属于类的某个实例,通过这个实例调用它,对类的其他实例不产生影响.
  • 类方法即该类的静态方法
方法属于这个类本身,不属于他的任何实例
	意思就是说,这个方法可以不通过实例调用,并且所有的实例都共享这一个方法,对方法的调用各个实例相互可见
  • 静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员函数不能访问非静态的成员
  • 3种构造函数分别是a(基类的构造函数),b(成员对象的构造函数),c(派生类的构造函数 )这3种构造函数的调用顺序为: abc

补充

1.eclipse的简单介绍

2.软件设计原则

  • 高内聚,低耦合
尽可能在一个类中实现,减少类与类之间的联系
  • 对外开放,对内关闭
在当前系统基础上可以添加类,已存在的代码不去修改

3.关键字instance of

obj instanceof Person
	——判断obj对象是不是Person

4.拷贝

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值