2021-10-30


1 图


详见https://www.pdai.tech/md/outline/x-outline.html

2 面向对象

面向对象的三个特征

封装:将对象的实现细节隐藏起来,然后通过一些公用的方法来暴露该对象的功能

优点:

减少耦合: 可以独立地开发、测试、优化、使用、理解和修改

减轻维护的负担: 可以更容易被程序员理解,并且在调试的时候可以不影响其他模块

有效地调节性能: 可以通过剖析确定哪些模块影响了系统的性能 提高软件的可重用性

降低了构建大型系统的风险: 即使整个系统不可用,但是这些独立的模块却有可能是可用的


继承:继承实现了is-A 的关系,子类作为一种特殊的父类可以获得父类的非private的属性和方法;继承应该遵循里氏替换原则,子类对象必须能够替换掉所有父类对象。


多态:是指子类的对象可以直接付给父类的变量,但运行时仍然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时,可能会有不同的表象特征。

父类的引用指向子类的对象成为:向上转型

多态分为:编译时多态和运行时多态

编译时多态:主要指方法的重载

运行时多态:主要指程序重定义的对象引用所指向的具体类型,只有在运行时才能确定


类是对象的抽象,对象则是类的实例。

对象是Java程序的核心,所以Java里对象具有唯一性,每个对象都有个标识来引用,如果失去了标识,这个对象就会变成垃圾,等着被垃圾回收器回收。Java语言不允许直接访问对象,而是通过对 对象的引用来操作对象。

3 类图

1、泛化关系Generalization:用来描述继承关系,在java中使用extends关键字

2、实现关系Realization:用来实现一个接口,在java中使用implements关键字


3、聚合关系Aggregation :表示整体由部分组成,但是整体和部分不是强依赖关系,整体不存在了但是部分还会存在


4、 组合关系Composition:组合关系和聚合关系不一样,组合关系中的整体和部分是强依赖关系,整体不存在了,那部分也不存在。公司和部门是组合关系,公司和员工是聚合关系。


5、关联关系 Assocaition:表示不同类对象之间有关联,是一种静态关系。在最开始就可以确定,可以用一对一,多对一,多对多这种关联管理表示,学生和学校是关联关系,一个学校可以用很多学生,但是学生只能属于一个学校。在运行之前就可以确定



6、依赖关系Dependency :与关联关系不同的是,依赖关系是在运行过程中起作用的,A类和B类是依赖关系,主要有三种形式:

A类是B类中的(某方法中的)局部变量

A类是B类方法中的一个参数

A类向B类发送消息,从而影响B类的变化


4 数据类型


Java语言支持两种类型的变量:基本类型和引用类型

引用类型包括类,接口,和数组类型,还有一种特殊的null类型

Tips:

1 变量相当于一个有名称的容器,该容器用于装各种不同类型的数据

2 自动类型转换,范围小的赋值给范围大的

       char->int

byte->short->int->long->float->double

3 表达式类型的自动提升

当一个算数表达式中含有多个基本类型时,整个表达式的数据类型会发生自动提升

所有的byte,short,char类型被提升为int

4 a=5

  b = a++b=5,a=6

  b = ++a b=6,a=6

  ++放在左边,先把操作数加1,然后把操作数放入表达式中运算。(--同理)

  ++放在右边,先把操作数放入表达式中运算,然后把操作数加1。(--同理)

5 数组:

int[]是一种引用数据类型,数组必须先初始化然后才能使用

基本类型数组初始化                              引用类型数组初始化

int[] a;

a = new int[5]

for(int i = 0 ;i<5;i++){

       a[i] = 10+I;

}




1 static

Static是一个特殊的关键字。可以用来修饰方法,成员变量。

Static修饰,表示这个属性只属于类本身,而不属于该类的单个实例,由static修饰的成员变量和方法一般叫做类变量,类方法也叫静态变量静态方法。不使用static修饰的方法和变量也叫做实例变量,实例方法。Static真正的作用是用于区分 成员变量 方法 内部类 初始化块这四种成员是属于类本身还是实例的。

静态成员不能直接访问非静态成员(前者属于类 先加载,后者属于对象(实例化以后才存在),一个已经存在东西去加载一个不存在的东西是不合理的,会报错)

2 类和对象

定义类是为了重复创建该类的撕裂。同一个类的多个实例具有相同的特征。而类则是定义了多个实例的共同特征。类是抽象的,实例是具体的。

Car c = new Car() ,在代码中实际上产生了两个东西:一个P变量,一个是Person对象。

当一个对象被创建以后,他被保存在堆内存中,java程序不允许直接访问堆内存中对象,只能通过该对象的引用操作该对象。也就是说,不管是数组还是对象,都只能通过引用来操作他们。

Java语言是静态的。一个类被定义以后,只要不在重新编译这个文件,该类和该类的对象所拥有的方法是固定的,永远不会变


3 参数传递机制

Java里方法参数的传递方式只有一种,值传递。


当程序执行swap()方法时,系统进入swap()方法,并将main()方法中的a b 变量作为参数传入swap()方法,传入的只是a b 的副本,而不是a b本身,进入swap()方法以后,系统产生了4个变量,这4个变量在内存的存储示意图入下图所示


main()方法中调用swap()方法,main方法还没有结束,因此系统为两个方法分别分配栈区,用于保存两个方法的局部变量。Main方法中的变量作为参数值传入swap方法,实际上是在swap方法栈中重新产生了两个变量a b,并将main方法中a b的值赋给swap方法中的两个变量(相当于对swap方法中的形参进行初始化)因此系统中存在2个a 2个b,只是存在不同的方法栈中。

对象的引用:

对重保存了对象本身,栈内存中保存了引用该对象的引用变量。


类的成员变量无需显示的初始化,只要为一个类定义了一个类变量或实例变量,徐彤就会在这个类的准备阶段或创建该类的实例是进行默认初始化,成员变量默认初始化时的负值规则与初始化数组元素的赋值规则完全相同


Car c = new Car() 如果代码是第一次使用Car类,则系统通常会在第一次使用Car类时加载这个类,并初始化这个类(含有静态变量的话,内存分配空间)


栈内存中的变量无需系统垃圾回收,随着方法或者代码块的运行结束而结束。因此局部变量作用域是从初始化该变量开始,到方法或者代码块运行结束而结束。因此局部变量只保存基本变量或者对象的引用,因此局部变量所占的内存区域通常比较小。


4 构造器

当程序调用构造器时,系统会先为该对象分配内存空间,并为这个对象执行默认初始化,这个对象已经产生了——这些操作在构造器执行之前就都完成了。也就是说,当系统开始执行构造器的执行体之前,系统已经创建了一个对象,只是这个对象还不能被外界访问。只能在构造器中通过this来引用。当构造器的执行体执行结束后,Hegemony对象作为构造器的返回值被返回,通常还回复给另一个引用类型的变量从而让外部程序可以访问该对象。


子类不会获得父类的构造器,但是可以在自己的构造器中调用父类的构造器。

当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行。不仅如此,执行父类构造器时,系统会再次上溯执行其父类构造器,以此类推,创建任何java对象,最想执行的总是java.lang.Object类的构造器


输出结果

Creature 的无参数构造器

Animal 的1个参数构造器狼

Animal 的2个参数构造器 name:狼age:3

Wolf 的无参数构造器

如果没有显示的调用父类的构造器,则调用父类的无参构造器,如果不存在则会报错

去掉第三行后的结果:

Creature 的无参数构造器

Animal 的无参数构造器

Wolf 的无参数构造器


5 初始化块,变量加载机制


5.1 继承的变量

子类是一种特殊的父类,因此父类包含的范围总比子类大,所以认为父类是大类,子类是小类(子类是父类的一种扩展)


重写和重载:

重写:发生在父类和子类之间

两同两小一大:

方法名相同,形参相同

返回值类型小于或等于父类,子类方法声明或发生的异常小于或等于父类

方法的访问权限要比父类方法的访问权限更大或相等


重载:发生在不同类之间

两同一不同

同一个类,方法名相同

参数列表不同

5.2 隐藏

父类和子类中都定义了相同的名字的变量,在实例化以后,子类中的实例变量会隐藏父类中的变量。系统创建子类对象的时候,实际上会为子类对象分配两块内存,一块用于存储在子类中定义的变量,一块用于存储从父类继承得到的相同名字的实例变量。

如果某个方法中访问名字为a的成员变量,但是没有显示的指定调用者,则系统查找a的顺序为:

1、查找该方法中是否有名为a的局部变量

2、查找当前类中是否有名为a的成员变量

3、查找当前类的直接父类中是否包含名为a的成员变量,一次向上溯源,直到Object类,如果找不到,最后会报错。

当系统创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为他从父类继承得到的所有实例变量分配内存,即使子类定义了与父类同名的实例变量。

C有父类B,B又集成A,A中定义了2个,B中定义3个,C中定义2个实例变量,最终这个对象会保存3+2+2个变量。

5.3 多态

Java的引用变量有两个类型:编译时类型和运行时类型

子类是一种特殊的父类,所以java允许将子类的对象直接赋给父类的引用变量。无需任何类型转换,这种成为向上转型。

对象的实例变量不具备多态。只有方法具备。

引用变量在便一阶段只能调用其编译时类型转所具有的方法,但运行时则执行他运行时类型所具有的方法。

Object p  =new Person();p只能调用Object类的方法,而不能调用Person中的方法。

通过引用变量来访问包含的实例变量是,系统总是试图访问他编译时类型所定义的成员边浪,而不是他运行时类型所定义的变量。

5.4 初始化块

初始化块是java类里面可以出现的第四种成员

创建java对象的时候,系统是总是先调用该类里定义的实例初始化块,如果一个类里面定义两个实例初始化块,则前面的定义的先执行,后定义的后执行。

初始化块虽然也是java类的成员,但他没有名字,没有标识,没有办法通过类,对象来调用初始化块,实例初始块之创建java对象隐示执行,而且在构造器执行之前自动执。

Java创建一个对象时,先为该对象的所有实例变量分配内存(前提是该类已经被加载过了)


接着程序开始对这些实例变量执行初始化,其初始化的顺序是:先执行实例初始化块或声明实例变量时指定初始值,在执行构造器里面指定的值。


其实java文件编译后,初始化块会被还原到每构造器中,并且位于构造器前面

创建一个java对象时:

先执行Object类实例初始化块,然后执行Object类构造器,一次向下执行欺父类的实例初始化块,父类构造器……最后才执行该类的实例初始化块和构造器,返回该类对象。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容