一、类与对象与方法
类:
从现实世界的具体事物里抽象出来的对于一类事物的总称。具有某种特征和行为的事物的抽象。其特征称为事物的变量(属性),事物的行为用方法表示。
圆点运算符可以理解为汉语里的 “的”。
字段(属性):实例变量与类变量
方法(methods)实例方法与类方法
内部类(枚举是一种特殊的类)
注解是一种特殊的接口
实例初始化器:初始化实例变量
类初始化器:初始化类变量,首次主动使用一个类时就会初始化该类
构造方法,三者都不是类的成员
声明方法:[修饰符],返回值类型,方法名称,([形式列表])(throws异常类型){}
开辟空间的时候不需要为方法开辟空间,只是为字段开辟空间。
方法的注释形式:/** */ 。
通过对象头可以找到对应方法区中的类,对象头下是实例数据区,里边存放着实例信息,空间是连续的,与类变量无关,只与构造方法有关。
-
所有的实例方法执行时,都会存在一个this,就是对象头的地址。this是一个局部变量,
-
函数的返回值:
[修饰符] 返回类型 方法名 [形参列表] [throws 异常类型]
当运行带动public static void main(String[] )的类时,就会首先启动Java虚拟机,Java虚拟机就会启动一个名称为main的线程,main线程调用main方法并为其传入参数
在同一个类中可以省略类变量之前的类名
通过类名.方法名([参数])形式调用类方法
实例方法: 应该通过实例来调用
类方法: 应该通过类名来调用
二、Arrays类中的类方法
tosring方法
sort方法:sort() 方法用原地算法对数组的元素进行排序,并返回数组。
binarySearch方法(二分查找):前提数组有序,在集合中找到一个大于(小于)目标数t的数x,使得集合中的任意数要么大于(小于)等于x,要么小于(大于)等于t。
copyof方法 复制元素返回新的数组
如果key包含在数组中,返回key的下标,否则返回(-(插入点)-1)
copyOfRange方法
将数组中(from,to)之间的数组复制,前闭后开
main线程调用main方法会产生与相关的栈帧并压入虚拟机栈栈顶。
对象:
是抽象概念的具体实例
使用new关键字创建对象除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
类中的构造器也称为构造方法,是在进行创建对象的时候要调用的。并且构造器有以下两个特点:必须和类的名字相同;必须没有返回类型,也不能写void
类实例化后返回一个自己的对象(类的具体实例)
一、return用法:
在有返回值的方法中,返回方法指定类型的值,同时结束方法执行;
(也可以用在返回值为void的方法中,用来终止方法运行;
2、break和return区别: break:是用来跳出循环的,例如for,while,do-while都可以跳出,但不跳出函数。
return:是使整个函数返回的,后面的不管是循环里面还是循环外面的都不执行。
return 表示一个方法的终止,不一定返回值。从哪里调用就返回到哪里。
return 返回的是与方法类型相同的值。
所有的方法都包含return,表示函数的结束 。
补充:调用任意方法都会产生与之对应的栈帧。
被调用的方法对应的栈帧会压入到虚拟机栈栈顶。(虚拟机栈也被称作方法栈或者方法调用栈)。
当方法结束时,其对应的栈帧会弹出虚拟机栈。
栈帧中包含局部变量表和操作数栈。
方法:方法头 + 方法体
包含部分:修饰符(public,static,final),返回值类型(int void return返回参数值//终止方法),方法名,
参数类型(传参类型,可以选择:实参,形参),方法体()
实参:调用方法时实际传给方法的参数
形参:在方法被调用时用于接受外界出传入的参数(相当于占位符) 。
能具体的实现某一个功能的集合或组件。
命名规则:首字母小写,后面按照驼峰命名法命名。 见明知意
方法 = 自定义函数(C语言中)
方法包含与类或对象中,在其他地方被引用,方法只完成一个功能。
方法的调用:
当方法返回一个值的时候,方法调用通常被当做一个值
int larger = max(30,40);
如果返回值是void,方法调用一定是一条语句。
System.out.println("Hello,word !");
方法的重载:
就是在一个类中有相同的函数名称但是形参不同的函数
方法名称必须相同
参数列表必须不同(个数不同或类型不同、参数排列顺序不同等)
在同一个类中存在多个同名不同参,他们相互之间构成重载
同名:方法名称必须完全相同
不同参:参数个数,类型,参数类型的顺序(不必考虑因素:方法的修饰符,返回类型,抛出的异常)
重载方法根据参数个数,类型,类型顺序来确定自己调用呢个方法。
String:可变长参数(也被叫可变/变长参数)
可以根据接受数组传参
对于可变长参数来说,在方法内部完全可以视作数组来处理
使用规则:
必须出现在(其他参数之后)参数列表末尾
同一个方法的参数列表中至多出现一个可变长参数
二、构造方法
构造方法(函数)也是方法的一种,它只是一个特殊的方法。
它是用来给类实例化成对象时调用的方法,与类同名的方法。
当类实例化一个对象时会自动调用构造方法。
每个类在构造成对象时必须要调用构造方法。
构造不是成员不能被继承。
语法格式 [访问修饰符] 构造方法名([参数类型 参数名,参数类型 参数名……]){ 完成构造方法的功能; }
其中[ ]是可选的,修饰符只能public 或不写
方法的参数类型(形参)可以有,也可以没有,如果有多个参数类型要加逗号(英文)分隔,最后一个参数不要加逗号(英文)。
方法的参数类型可是基本数据类型,也可以是引用类型,但不能加void。
TravesalFile#遍历文件 file #exists();#实例方法 file.exists();#类方法用于判断fod所表示的目录或文件在磁盘是否存在 file.isFile();#判断fod是否表示文件 file.isPirectory();#判断fod是否表示目录
通过“new构造方法([参数])“形式来创建实例(也叫对象)
在编译阶段编译器会自动添加一个构造方法;
公开的(public);与类同名;没有参数;在构造方法中没有任何操作(除必须操作外)
当显示书写了带参数的构造方法时,编译器不再提供默认构造
通过调用无参构造来创建对象(也叫实例)
构造方法的重载:多个构造方法相互重载
含参构造:用参数可以初始化本类所有的实例变量,通过带有参数的构造方法可以实现根据用户传递的参数值来初始化实例变量。
三、递归
程序调用自己本身的编程技巧
-
递归分为两种,直接递归和间接递归。
-
直接递归称为方法自身调用自己。
-
间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
面向对象编程(物以类聚,分类思维模式 oop:面向对象编程)
以类的方式组织代码,以对象的组织(封装)数据。
抽象:
三大特性
封装:数据包装在一个盒里对外提供一个入口
继承:子类继承父类
多态:
类 = 属性+方法
先有对象后有类,之后抽象出概念
在类体中被static修饰的变量称为类变量
在类体中没有被static修饰的称为实例变量
-
Java是值传递
一、构造
-
默认构造
所谓默认构造是在编译阶段由编译器自动为类添加的公开的无参数构造方法。
(当某个类中没有显式书写任何构造方法时,编译器才会为该类自动生成默认构造方法)
package com.kaifamiao.cons; public class Hui { public String fullName; } -
实例初始化器
实例初始化器 俗称 普通代码块。
package com.kaifamiao.cons; public class Hui {public String fullName; public char gender; // 实例初始化器 { // 初始化实例变量 fullName this.fullName = "回族兄弟"; } // 实例初始化器 { // 初始化实例变量 gender this.gender = '男'; }
}
-
有参构造
在类初始化器中写死了参数值
在有参构造方法中用户传入参数值
编译阶段不再为类生成默认构造方法
-
构造方法重载
同一个类中的所有构造方法的名称都是与类名同名的,
如果同一个类中存在多个构造方法的参数是不相同的,则它们相互之间构成重载。
package com.kaifamiao.cons; public class Hui {public String fullName; public char gender; // 实例初始化器 { // 初始化实例变量 fullName this.fullName = "回族兄弟"; } // 实例初始化器 { // 初始化实例变量 gender this.gender = '男'; } public Hui(){ super(); } public Hui( String fullName, char gender ){ super(); // 将构造方法的参数值赋值给实例变量 this.fullName = fullName; this.gender = gender; } }
-
调用另一个构造
在有参数构造方法中通过 this()
来调用无参数构造方法:
package com.kaifamiao.cons; public class Hui { public String fullName; public char gender; // 实例初始化器 { // 初始化实例变量 fullName this.fullName = "回族兄弟"; } // 实例初始化器 { // 初始化实例变量 gender this.gender = '男'; } public Hui(){ super(); } public Hui( String fullName, char gender ){ this(); // 将构造方法的参数值赋值给实例变量 this.fullName = fullName; this.gender = gender; } }
通过 this([参数列表])
可以调用本类中除当前构造方法之外其它任意构造方法。
二、修饰符
1、修饰符
1.1、访问修饰符
访问修饰符(access modifiers) 也称作访问控制符或权限修饰符,用于控制类以及类中成员的的访问权限。
public 公开的
protected 受保护的
private 私有的
四个访问级别: 公开的 受保护的 默认的 私有的
访问级别 | 访问修饰符 | 在哪里可以访问 | flags |
---|---|---|---|
公开 | public | 本类、本包其它类、子类、其它包中的类 | 0x0001 |
受保护 | protected | 本类、本包其他类、子类(子类与父类在不在同一个包无所谓) | 0x0004 |
默认 | 本类、本包其它类(是不是子类无所谓) | 0x0000 | |
私有 | private | 本类 | 0x0002 |
2、控制类的访问
对于一个外部类来说,要么用 public
修饰,要么不书写任何修饰符。
2.1、公开级别
采用 public
修饰符修饰的外部类可以在本包中使用,也可以在其他包中使用。
package com.kaifamiao.enca.first; // 在class之前显式指定访问修饰符为public // public 表示 "公开的" public class Panda { }
在同包其它类中使用时不必书写 import
语句
package com.kaifamiao.enca.first; public class FirstTest { public static void main(String[] args) { // 同包中的类不必 import 导入 Panda p = new Panda(); System.out.println(p); } }
在其它包的类中使用时,需要首先import
导入:
package com.kaifamiao.enca.second; // 需要通过 import 导入非同包的类 import com.kaifamiao.enca.first.Panda; public class SecondTest { public static void main(String[] args) { Panda p = new Panda(); System.out.println( p ); } }
2.2、默认级别
若某个外部类没有public
修饰则表示其访问级别是默认级别,即仅限本包内其它类使用。
package com.kaifamiao.enca.first; class Loong { }
在同包其它类中使用 Loong
类:
package com.kaifamiao.enca.first; public class FirstTest { public static void main(String[] args) { // 同包中的类不必 import 导入 Loong x = new Loong(); System.out.println( x ); } }
但到了其它包中,即使使用 import
语句导入 Loong
类,也不能使用该类。
package com.kaifamiao.enca.second; import com.kaifamiao.enca.first.Loong; public class SecondTest { public static void main(String[] args) { Loong x = new Loong(); System.out.println( x ); } }
因为在 import
语句中已经发生编译错误,因此后续的创建实例也是有错误的。
对于 非成员类 来说,不能使用 protected
和 privite
来修饰。
Java语言规范中关于protected
和 privite
修饰类的说明:
The access modifiers protected and private pertain only to member classes.
3、修饰类的成员
3.1、公开级别
用 public
修饰的 字段(fields) 、方法(methods) 、成员类(member classes) 的访问权限都是公开级别。
此时可以在 本类中、同一个包的其它类中、其它包的类中 都可以访问。
3.2、受保护级别
用 protected
修饰的 字段(fields) 、方法(methods) 、成员类(member classes) 的访问权限都是受保护级别。
此时可以在 本类中、同一个包的其它类中、子类中 都可以访问。
其中子类可以与父类在同一个包,也可以不在同一个包。
3.3、默认级别
在 字段(fields) 、方法(methods) 、成员类(member classes) 之前没有显式设置任何访问修饰符,
此时就说他们是 默认访问权限级别 。
默认访问权限级别 仅限在 本包中使用,比如 本类中、本包其它类中。
至于本包中的其它类是否是子类,无所谓。
3.4、私有级别
用 private
修饰的 字段(fields) 、方法(methods) 、成员类(member classes) 的访问权限都是私有级别。
此时仅限类中可以访问,在本类之外一律不准访问。
4、修饰构造
4.1、公开的构造
用 public
修饰的 字段(fields) 、方法(methods) 、的访问权限都是公开级别。
本类中、同一个包的其它类中、其它包的类中 都可以访问。
4.2、受保护的构造
用 protected
修饰的 字段(fields) 、方法(methods) 、的访问权限都是受保护级别。
在本类中同一个包的其它类,子类都可以访问,子类可以与父类在同一个包,也可以不在同一个包。
4.3、默认访问级别的构造
在 字段(fields) 、方法(methods) 之前没有显式设置任何访问修饰符,
默认访问权限级别 ,仅限在本包中使用
4.4、私有构造
用 private
修饰的 字段(fields) 、方法(methods) 的访问权限都是私有级别。
仅限类中可以访问,本类之外一律不准访问。
封装:(encapsulation)
1、封装的含义:封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。
2、封装的作用:封装的作用在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。
3、如何封装:封装提供了一个有效的途径来保护数据不被意外的破坏。相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fields)定义为私有的(private)在很多方面会更好。私有的数据可以用两种方式来间接的控制。第一种方法,我们使用传统的存、取方法。第二种方法我们用属性(property),使用属性不仅可以控制存取数据的合法性,同时也提供了“读写”、“只读”、“只写”灵活的操作方法。
4、什么情况下封装:编写实例类时,用到封装有很多好处,比较实际的:
拒绝直接调用声明字段,保护内部数据,更安全; 在编程中可达到缓存的效果,执行效率高; 重复调用,避免代码冗余,程序编写效率高。
成员变量也称属性,分为类的成员变量和对象的(实例变量)成员变量.
非成员变量指局部变量
一、其他修饰符
abstarct final interface native static strict synchzonized
transient volatile
static
表示属于类的或于类相关;被static修饰的变量被称作类变量(class varible)
被static修饰的方法称作类方法(class method);被static修饰的代码称作类初始化器(static initial )俗称静态代码块
final
表示最终,不可更改的;被final修饰的是最终变量
二、封装(encapsulation)
Setter:用于为私有的实例变量赋值(设值器)
若参数名称与实例变量名称相同,则可以通过”this.实例变量名”来使用实例比变量。
等号之前的“this.name”表示当前对象中的实例变量。
等号之后的“name”表示当前方法的参数名称。
Setter方法名称是set+字段名称(首字母大写)
.name之前的变量地址与调用的Setter方法中this的地址一致。
getter:用于获取私有的实例变量的值(getter也称作取值器)
getter方法名称是Get+字段名称(首字母大写)
三、super与this
-
this是什么:
可以理解为是一个指向当前实例(对象)的一个引用(或指针)
(可以将this理解为一个变量,其中存储了当前实例(即当前对象)在堆内存中的首地址)
this的三种用法:
(1)、访问实例变量 ( 取值 和 赋值 ) (2)、调用实例方法
(3)、在构造方法中调用本类的其它构造方法
this可以在哪里使用:
(1)、实例初始化器(俗称普通代码块) (2)、构造方法 (3)、实例方法
this不能使用在类方法(静态方法)中、也不能使用在类初始化器(静态代码块) 中。
super是什么?
与this不同,super不可以理解为一个引用变量 ; super不可以以单独使用,
super用来访问从父类继承的成员、调用父类构造方法
super的三种用法:
(1)、访问从父类继承的实例变量 (取值 或 赋值)(2)、调用从父类继承的实例方法
(3)、在本类构造方法中调用父类构造方法
super可以在哪里使用:
(1)、实例初始化器(俗称普通代码块) (2)、构造方法 (3)、实例方法
super不能使用在 类方法(俗称静态方法)中、也不能使用在 类初始化器(俗称静态代码块) 中
super
通过 "super([参数])" 形式调用父类构造方法
通过 "super.实例变量名" 为从父类继承的实例变量赋值
通过 "super.实例变量名" 获取从父类继承的实例变量的
通过 "super.实例方法名([参数])" 形式来调用从父类继承的实例方法
this
通过 "this([参数列表])" 形式调用本类其它构造方法
通过 "this.实例方法名([参数列表])" 形式调用实例方法
通过 “this.实例变量名” 来获取实例变量的值
通过 “this.实例变量名” 来为实例变量赋值
四继承
鼻祖<=====父类 子类到父类一般化过程(泛化)
|| 父类到子类特殊化过程(特化)
子类< ====>||<====>子类 父类与子类的关系为继承
子类
对于类与类间的继承来说,extends关键字后只能跟一个直接父类;定义类时未通过extends显式指定其父类就是Java.lang.Object
什么是继承
使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。即为继承父类的特征与行为。
如何实现继承
类与类之间继承用extends实现
为什么继承
为了实现程序的复用以及扩展。
继承了什么
一说:(Java编程规范)
子类与父类在同包时,可以从父类中继承公开的,受保护的,默认的成员(主要关注字段与方法)
子类与父类在不同包时,可以从父类中继承公开的,受保护的的成员(主要关注字段与方法)
一说:基于内容理解,存储及访问修饰符
子类可以继承父类中所有成员,但是受访问修饰符的影响,子类可能不能直接访问它所继承的成员。
继承特点
只支持单继承,一个父类只允许有一个父类。
可以拥有自己的属性和方法
也可以拥有父类的属性和方法
子类可以重写覆盖父类的方法
一、object
object类中的toString 用来获得指定对象(实例)的描述信息,hashcode用来获得指定实例(对象)的哈希码值。
用Integer类中的toSting 方法将十进制数转化为十六进制后输出
获得引用变量O所指向的堆区中的实例(对象)的类型
返回值是Java.lang.class类型的实例
class c = O.getClass();
获得引用变量(所指向的实例(对象))所表示的类的类名
equals用来比较当前对象是否与另一个对象相等
Object 类常用方法:
to String ();返回字符串
hashcode ();返回int
get class();返回class
引用变量 instance of T 类型
解释:引用变量所引用的对象是 T类型吗?若是返回true否则返回false
二、equals与hashcode
(1)同一个对象多次调用hashCode()方法应该返回相同的值; (2)当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()应该返回相等的(int)值; (3)对象中用作equals()方法比较标准的Filed(成员变量(类属性)),都应该用来计算hashCode值。
1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。 3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
hashcode 常规协定:
对同一对象调用hsahcode方法时,返回的数必须一致
将equals中比较时使用的信息修改,会导致产生新的哈希码值
根据equals方法,两个对象相等,每个对象调用hashcode所生成的结果相等
子类不能重写父类的final方法
子类中重写的修饰符的范围必须大于父类的范围。
三、重写或覆盖
当子类中重新定义了与从父类中继承的 同名、同参、同返回 的方法,则称子类中的方法 覆盖(或重写) 了从父类继承的同名方法
@Override public String toString(){ return "大家好,我是" + fullName + "," + gender + ",今年" + age + "岁" ; }
所有的引用类型的变量都应该使用 equals 来比较 (这里使用String类的equals来比较两个字符串是否相等)比较的是地址值
四、课堂
类初始化时先执行父类的<clinit>(类构造方法)再执行子类的<clinit>(类构造方法)
psvm的方法的类被称作启动类
直接运行启动类的main方法会导致该类被初始化
当子类被初始化时会先初始化其父类
被final 修饰的类是最终类
多态其一:polymorphism
见名知意,多种形态
编译阶段,同一个类中多个同名不同参的方法,就是多种形态,因此被称作<编译时多态>
方法的重载也是编译时多态
目录