面向对象
2023-07-24 09:03:42 0 举报
AI智能生成
登录查看完整内容
面向对象基础知识梳理
作者其他创作
大纲/内容
封装就是隐藏类的内部信息(属性和方法),不允许外部程序直接访问,而是通过公有的方法才能完成访问(赋值方法get()和取值方法set())
概念
关键字 private(只能本类中访问)
封装属性:私有化属性,提供 无参构造、get和set方法
封装方法:若只需要在本类中调用该方法不希望外部调用,则用private修饰
封装
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可
由来
关键字 extends
单继承
不能多继承,可以多层继承
Java对继承的支持性
单根性
传递性
两大特性
当父类的方法不能满足子类的需求,子类可以重写父类的方法
作用
新增方法/属性
重写后,子类对象调用的是重写后的方法,不能调用父类的方法而且父类方法也不能被删除,否则报错
方法重写只发生在继承中的子类中
子类中重写的方法,返回值类型,参数名称,参数列表与父类中被重写的方法必须一致。(方法体发生改变,可以修改访问权限:但子类只能扩大权限不能限制权限)
子类和父类同名同参的方法都应该同时是static或非static的static(不是重写)static方法是类的方法,子类无法重写非static可以重写
注意点
重载:必须修改
重写:可以修改
参数列表
重载:不能修改
重写:可以修改(类型应该是父类方法中返回类型的子类)
返回类型
重载:可以修改
重写:可以修改,不能做出更严格限制
访问
与方法重载的区别
方法重写
代表父类、超类。用于在子类中访问父类中的属性或者方法
当子类中重写父类的方法时,如果再在子类的方法体中调用父类中的方法,则只能使用super.方法名()
说明
只能在子类中使用
使用区域
在子类中访问父类中的实例变量
在子类中访问父类的实例方法
在子类中访问父类中的构造方法
代表当前这个对象,也就是:当前谁调用这个方法则this代表的就是谁
描述
在当前类(本类)中使用
this关键字访问实例变量或实例变量时,查找顺序:先在当前类中找该实例变量或实例方法,如果找不到则再去父类中找该实例变量或实例方法
查找顺序
this
代表父类/超类
因此,得到结论:访问父类中的实例变量或实例方法时,使用super.查找速度相对更快或者执行效率更高。
直接到父类中查找实例方法或实例变量
super
访问目标
与 this 关键字的区别
super关键字
父类也叫做超类,也叫做基类superclass,子类也叫做派生类subclass
子类继承父类时,没有继承父类的构造方法
子类继承了父类,就继承了父类的方法和属性。
先父后子
创建子类对象时先默认执行父类的无参构造器( 子类构造方法中默认第一行添加了 super(); )若指定调用父类有参构造需要声明 super(参数)或调用this(···); 此时super()被覆盖
super(···)和this(···)不能同时出现在同一构造方法中
super(···)或this(···)调用语句只能在构造器中的第一句出现
所有类默认继承Object类
继承
多态是指同一行为,通过不同的具体事物,具备多种不同的表现形式。
良好的扩展性(当父类作为方法的参数时可以接收多种子类)
减少代码冗余性
意义
重写
父类引用指向子类对象/子类对象赋给父类引用(向上转型)
满足条件(三点缺一不可)
当构成多态后,引用对象是父类的类型,只能访问父类中公有的属性和方法此时调用该对象的方法显示是父类的,但结果是子类的。(调用方法时会先去父类中查找有没有该方法,无则报编译错误,有则去子类中查找有没有重写的方法,如有则调用子类重写后的方法,如无则使用父类方法。)属性只能调用父类的属性(要想调用子类的属性或独有方法需要向下转型/强制类型转换)
当构成多态时,父类的引用中存放的是那个子类的对象,则父类的引用就可以转换那个子类类型
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A 的值为true。
使用说明
instanceof
在进行向下转型之前,必须先判断,判断被转换的父类的引用与预期要转换的类型是否一致,一致就执行转换操作,反之不执行。
向下转型的注意事项
类型转换
多态中的动态绑定技术
多态
三大特性
构造方法的名字与类的名字一致
它不声明返回值类型。(与声明为void不同)
不能被static、final、synchronized、abstract、native修饰
不能有return语句返回值
是一种特殊的方法 有这些特点
创建对象;初始化对象
有参构造器
无参构造器
分类
默认存在无参构造,但有参构造会覆盖无参,所以存在有参构造时要显式声明无参构造
构造方法也构成方法的重载
构造方法
代表调用该方法的对象本身(该对象的地址)
在同一个类中,局部变量的名字可以和成员变量的名字是可以相同的,不报错,但是局部变量优先,也就是:就近的优先,如果非要访问成员变量,则必须使用this。
访问成员变量(区分成员变量和局部变量)
this()无参构造方法
this(参数)有参构造方法
this在构造方法中必须放在第一行
访问构造方法
访问实例方法
this访问属性和方法时,若在本类中未找到,则去父类中查找
在构造方法中this不能调用自身(会出现递归死循环)
首行默认super()若不放在第一行会与super重复调用父类构造方法,出现安全性问题
this在构造方法中调用构造方法必须放在首行
this关键字
static表示静态的 可以修饰属性、方法、代码块、内部类以及实现静态导入
在类中声明的变量,称为属性或者叫做成员变量、或者叫做字段。那么属性面前如果加入static关键字修饰,称为静态变量,也叫做类的变量。如果属性前面没有编写static关键字,称为实例变量,也叫做对象变量
类名.变量名
对象名.变量名
访问方式
类变量由该类的所有实例共享
共享数据
都是变量
相同
不同
与实例变量的区别
当对象名中的值为null时,依然可以访问静态变量名,不会出现空指针异常,原因就是静态变量不属于某一个对象,而是当前这个类的所有对象都可以共享。
静态变量/类变量
有static
实例变量/对象变量
没有static
全局变量
方法前面编写static关键字,称为静态方法,也叫做类的方法。
类名.方法名()
对象名.方法名()
在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
因为不需要实例就可以访问static方法,因此static方法内部不能有this。
不能有this关键字
不能被重写/继承
静态方法/类方法
静态变量和静态方法,也可以访问实例变量和实例方法
可以访问
实例方法/对象方法
方法
修饰
若一个类想直接使用其他类中的静态变量,可以静态导入import static (包名.)类名.静态变量名
static关键字实现静态导入
见内部类--静态内部类
static关键字修饰内部类
由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是 public
JVM规定main方法是程序的入口,一般方法都是对象调用的,但在执行main方法前创建对象显然是不可能的,main方法加上static后就解决了该问题,类可以直接调用
该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数
main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员
main方法中的static
static
final表示最终的
可修饰 类、属性、方法
提高安全性和程序的可读性
表示该类是最终的(太监类/断子绝孙类),也就是:该类不能再被继承例如:String、Scanner、System
修饰类
表示该属性是最终的,也就是:该属性称为常量
修饰的属性为引用类型属性时,地址不能改变,但地址中的内容可以改变
命名规则:常量习惯用大写命名,若有多个单词,用下划线隔开
原因:节省空间,在堆内存中只存放一次,并且该类所有对象都可以共享。
一般final关键字与static关键字配合使用
被final修饰的成员变量必须被初始化后才能使用
修饰属性
表示该方法是最终的,也就是:该方法不能再被重写
修饰方法
final关键字
它用大括号“{}”将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块。
对Java类或对象进行初始化
通常用于初始化静态变量
静态代码块
非静态代码块/匿名代码块
静态代码块最先执行且只执行一次
匿名代码块在调用构造器时先于构造器执行一次
执行方式
代码块
首先由类装载子系统,将class类文件加载到运行时数据区(JVM内存)中,其次交给执行引擎去执行class文件,然后进行GC垃圾回收。
大致流程
有三种类装载器(待完善)
类装载子系统
Java虚拟机栈 Java Virtual Machine Stack,早期也叫Java栈,简称栈,主管Java程序的运行,它保存方法的局部变量、并参与方法的调用和返回。
入栈/压栈
出栈/弹栈
存放方法的 参数 和 局部变量等
栈帧
虚拟机栈
JVM内存最大的一块区域
执行new关键字时就会在堆中开辟新的空间
存放对象实例(属性及其数据)
堆(heap)
类加载器将class文件加载到内存之后,将类的信息存储到方法区中。
存储已被虚拟机加载的class信息。
① 这个类型的全限定名(包名.类名)
② 这个类型直接父类的全限定名
类型信息
属性名称、属性的类型
域信息
方法名称、方法的返回类型
方法参数的数量和类型
方法内容
存储内容
方法区(Method Area)
记录字节码指令执行的位置
程序计数器(Project Counter Register)
在方法内部声明,使用之前,必须初始化;存储在栈中,一旦方法使用完,变量就失效。
局部变量:
定义在类中,方法外,有默认值,存在堆中,对象使用完毕,就被gc()回收。
成员变量(属性):
本地方法栈(Native Method Stack)
分为五个区域
将class文件加载到内存中
运行时数据区(内存)
Java字节码的执行是由JVM 执行引擎来完成。
执行引擎
Java源码中Native 方法 就是典型的本地方法接口,作用就是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序。
本地接口库
JVM
强调步骤
面向过程
强调对象
面向对象
程序设计思想
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典 的棋谱,不同的棋局,我们用不同的棋谱。”套路”
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对 某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
1.私有化构造器
2.内部提供一个当前类的实例(已初始化)(且为静态的)
3.提供公共的静态方法,返回当前类的实例
方式一:饿汉式
与方式大致相同,不同的是提供的实例未初始化,当需要用到的时候(调用返回实例的方法)再初始化
目前还存在线程安全问题(未完善)
方式二:懒汉式
实现
减少系统性能开销
优点
网站的计数器
应用程序的日志应用
数据库连接池
读取配置文件的类
等等....
应用场景
单例设计模式
当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以 把不确定的部分暴露出去,让子类去实现。
模板方法设计模式
可以为其它对象提供一种代理以控制对这个对象的访问,屏蔽对真实角色的直接访问。
静态代理(静态生成代理类)
动态代理(动态生成代理类)(未完善)
代理设计模式
实例化对象,用工厂方法代替 new 操作。 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类(实际要new的类)解耦。
本质思想
简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的实例对象。
对于增加新产品,不修改代码的话,是无法扩展的。违反了开闭原则(对扩展开放;对修改封闭)
缺点
简单工厂模式
工厂方法模式
抽象工厂模式
工厂设计模式(未完善)
设计模式
概念:是对一类事物的描述,是抽象的。
行为(方法)
属性
包含
当一个类的定义出现在另一个类的类体中时,那么这个类叫做内部类,而这个类所在的类叫做外部类。
可让类和类之间的继承/实现更简化
让接口和抽象类也可以new
当一个类存在的价值仅仅是为某一个类单独服务时,那么就可以将这个类定义为所服务类中的内部类,这样可以隐藏该类的实现细节并且可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法。
使用场景
直接将一个类的定义放在另外一个类的类体中。
在A类中申明了一个B类,此B类就在A的内部,并且在成员变量的位置上,所以就称为成员内部类,由于此时的内部类没加static,所以叫做非静态内部类。
解读
使用方式
非静态内部类
静态内部类
成员内部类
匿名内部类
内部类
被abstract关键字修饰的类就抽象类
表示抽象
关键字:abstract
普通方法
不能有方法体
只能存在抽象类中
没有重写全部抽象方法的仍然是抽象类
抽象方法
抽象类不能被实例化,但可以通过子类创建对象(多态)(向上转型)
父类中的抽象方法虽然没有被子类直接使用,但也不能删除,否则子类无法重写该抽象方法。
可以定义构造器(因为被继承后需要加载子类属性和构造方法)
注意
父类提供抽象方法,交由子类进行具体实现
本质
概念:Java中的接口就是一种统一了实现子类的开发标准。但凡符合接口标准的子类都可以和接口做适配。
表示接口
实现:implements
关键字 interface
语法格式:先写extends在写implements
将功能封装——解耦
接口是抽象方法和常量定义的集合(JDK7及之前)
所有成员变量默认被 public static final 修饰
抽象方法默认被 public abstract修饰
没有重写全部方法可以作为一个抽象类
一个类可以实现多个接口,接口也可以继承多个接口(类不能多继承是因为当两父类出现同名方法,子类不知道继承哪个)(接口可以多继承,因为接口中都是抽象方法,继承哪个方法都无所谓)
多继承(多实现)的机制,弥补了java单继承的不足
没有构造器
不能被实例化,但可以通过子类创建对象,和继承关系类似,也是多态的一种形式
jdk9中可以有私有方法
当两个接口的默认方法同名由都被同一个类实现时,会出现接口冲突问题子类应该指明调用哪一个方法:类名.super.方法名()
接口中的默认方法
JDK8中接口的改进
接口(特殊的抽象类)
都不能创建对象,其实:抽象类和接口都是多态的一种形式
抽象类和接口中都可以编写抽象方法
子类或实现类都必须要重写抽象类或接口中的所有的抽象方法,否则子类或实现类就是抽象类
相同点
关键字不同
抽象类除了有有普通类所有内容,还有抽象方法
接口不同JDK版本内容不一样,JDK7及之前只有抽象方法和常量JDK8新增静态方法和默认方法,JDK9新增私有方法等
结构不同
抽象类要被继承(单继承),接口要被实现(可以多实现)
继承是一个 \"是不是\"的关系,而 接口 实现则是 \"有没有\"的关系。如果一个类继承了某个抽象类,则子类必定是这个抽象类的种类,而接口实现则是有没有、具备不具备的关系
不同点
抽象类与接口异同
抽象类
子主题
类
概念:是一类事物的实例,是具体的。
对象
类与对象
Object类是所有Java类的根父类
如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
概述
主要方法
当一个类继承另一个类后,子类对象调用方法会现在子类中查找该方法,若找不到再去父类中查找
当某方法只在父类中定义时,调用该方法会使用父类的属性若该方法又调用了其他的方法,那么还是按照上面的顺序,先从子类查找,找不到再去父类中查找。
疑问:为何调用方法时会出现Object类中的方法?
比较两个变量的值,相等则返回true
基本类型比较
比较两个引用的地址是否相等,相等则返回true
引用类型比较
==
不能比较基本数据类型
比较两个引用的内存空间地址是否相等,相等则返回true( 和 == 作用一致,源码中就是用==判断的)
未重写时
当用equals()方法进行比较时,对类File、String、Date及包装类 (Wrapper Class)来说,是比较类型及内容而不考虑引用是否是同一个对象;
先比较地址是否相同,相同直接返回true不同再看传进来的参数 instanceof String先强制转换成String类型再看长度是否相同,不同直接返回false,相同再将字符串转换成数组取出每一个比较,都相同返回true
源码解读
比较字符串是否相同,相同为true,不同为false
参数为null时结果为false
字符串常量池中只存储String类型,且存放的是String对象的引用而不是内容
举例:当执行 String a=“hello”;时,jvm会先在堆内存中找有没有“hello”,有则将该引用赋值给 a没有则在堆中新建一块内存,并将新的引用驻留在常量池中
方式①创建的对象只要等号右边的一样,就指向同一地址(常量池)
①String 引用名=“xx”;(字面量)
方式②是创建的对象指向不同的地址 但若xxx内容相同 用equals方法也会返回true(比较值)(执行new关键字就会在堆中开辟新的内存空间)
②String 引用名=new String(“xxx”);
补充:String类创建对象的两种方式
String类重写
被子类重写
使用equals方法时尽量把未知的变量放在括号中这样就算变量为null也不会报错,若放在前面 为null时,就会报空指针异常NullPointException
注意事项
equals()方法
经典面试题:==操作符和equals方法的区别
toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
在进行String与其它类型数据的拼接操作时,自动调用toString()方法
重写后就是以字符串形式打印对象的属性
快速展示类中的属性
toString()方法
基本类型对应包装类
针对八种基本数据类型定义相应的引用类型—包装类(封装类)有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
数据类型转换
大小写转换
数据转换
把包装类对象转换为byte字节
注意:byte类型范围为 -128-127 超过范围的会被缩小
byte byteValue()
-1
1
-33(ASCII码差值)
-1(true比false大)
例
比较两个包装类对象的大小
i1.compareTo(i2)
int compareTo(Integer anotherInteger)
把字符串转换为int整数
Character没有 parseXxx方法
static int parseInt(String s)
static Integer valueOf(int i)
Integer.valueOf(\"852\")同样字符串要符合对应的数字格式
static Integer valueOf(String s)
提供静态方法创建包装类对象
常用方法
由小到大
自动数据类型转换
由基本类型到包装类型
例题: Integer i3 = 69; Integer i4 = 69; System.out.println(i3 == i4);结果为true
例:Integer i1 = 789; //自动装箱
装箱
由大到小
强制类型转换
由包装类型到基本类型
例:int num = i1; //自动拆箱
拆箱
拆装箱
包装类
Object类
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。
四种访问权限修饰符
访问权限修饰符
0 条评论
回复 删除
下一页