Java基础02
选择排序
public static viod selectSort(int[] arr){
for(int m=0; m<arr.length-1; m++){
for(int n=m+1; n<arr.length;n++){
if(arr[m]>arr[n]){
int temp = arr[m];
arr[m] = arr[n];
arr[n] = temp;
}
}
}
}
冒泡排序
public static viod bubbleSort(int[] arr){
for(int m=0; m<arr.length-1; m++){
for(int n=0; n<arr.length-m-1;n++){
if(arr[n]>arr[n+1]){
int temp = arr[n];
arr[n] = arr[n+1];
arr[n+1 ] = temp;
}
}
}
}
排序函数
Arrays.sort(arr);//从小到大排序
最快的排序方式:希尔排序
数组查找
折半查找:前提是该数组为有序数组
package althorgrim;
/**
* 1、必须采用顺序存储结果
* 2、关键字必须有序
*/
public class BinarySearch {
public static int binarySearch(int a[],int goal){
int high=a.length-1;
int low=0;
while (low<=high) {
int middle=(low+high)>>2;
if (a[middle]==goal) {
return middle;
}
else if (a[middle]>goal) {
high=middle-1;
}
else {
low=middle+1;
}
}
return -1;
}
面向过程
- 面向对象是相对于面向过程而言
面向对象
- 类 :对现实生活中事物的描述。
- 对象 :这类事物,实实在在存在的个体。 (在堆内存中,new产生的实体)
- 成员变量 : 存在于堆内存中
- 局部变量 : 存在于栈内存中
匿名对象
- 匿名对象是对象的简化形式;
- 使用情况
- 当对象方法仅进行一次调用时;
- 匿名对象可以作为实际参数进行传递;
封装(Encapsulation)
- 封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
- 好处:
- 将变化隔离
- 便于使用
- 提高重用性
- 安全性
- 封装原则 :
- 将不需要对外提供的内容都隐藏起来
- 把属性都隐藏,提供公共方法对其访问
私有仅仅是封装的一种表现形式。
构造函数
- 函数名与类名相同
- 不用定义返回值类型
- 不写return语句
- 当类中自定义构造函数后,系统默认定义的构造函数就没有了
- 构造函数在对象一建立就运行
构造代码块
- 作用: 给对象进行初始化
- 对象一建立就运行,且优先于构造函数执行
- 构造代码块是给所有对象进行统一初始化
- 构造函数是定义不同初始化对象时使用
this使用:本类内部用到本类对象时使用
构造函数间调用只能使用this,且只能定义在构造函数的第一行,因为初始化需要先执行
static
- 用于修饰成员(成员变量和成员函数)(不能修饰局部)
- 被修饰后的成员具备以下特点
- 随着类的加载而加载
- 优先于对象存在
- 被所有对象共享
- 可以直接被类名调用
- 注意:
- 静态方法只能访问静态成员(方法和变量)
- 静态方法中不可以写this,super关键字
- 主函数是静态的
实例变量和类变量的区别:
- 存放位置:
- 类变量随着类的加载而存在于方法区中
- 实例变量随着对象的建立而存在于堆内存中
- 生命周期:
- 类变量生命周期最长,随着类的消失而消失
- 实例变量生命周期随着对象的消失而消失
弊端:
* 生命过长
* 访问出现局限性
方法设置为静态后,可以方便使用,但该类还是可以被其他程序建立对象,为了更加严谨,强制让该类不能建立对象,通过将构造函数私有化完成。
静态代码块
特点: 随着类的加载而执行,只执行一次
构造代码块
由对象初始化构造代码块
public class exam {
public static void main(String[] args) {
new StaticDemo();// a c9 b
}
}
class StaticDemo {
int num = 9;
StaticDemo() {
System.out.println("b");
}
static {
System.out.println("a");
}
//构造代码块
{
System.out.println("c" + this.num);
}
StaticDemo(int x) {
System.out.println("d");
}
}
结果:a c9 b
例子: Person p = new Person(“zhangxxx”,30);
- 因为new用到Person.class文件,会先找到该文件并加载到内存中。
- 若有静态代码块,则先执行static代码块内容,给Person.class类进行初始化。
- 在堆内存中开辟空间,分配内存地址。
- 在对内存中建立对象的特有属性,并进行默认初始化。
- 对属性进行显示初始化。
- 对对象进行构造代码块初始化。
- 对对象进行对应的构造函数初始化
- 将内存地址赋给栈内存中的p变量
方法区优先于对象存在,先加载
静态方法在栈内存中建立,不能访问堆内存(静态方法不能访问非静态方法)
继承
- 提高代码的复用性
- 类与类直接才产生了关系,才有了多态的特性
- 类与类之间要有所属关系才可以继承。is-a
- java只支持单继承(多继承容易带来安全隐患)(多个父类中定义了相同的内容,子类对象不确定运行那个)(改良后以多实现方式出现)
- 支持多层继承(想要使用体系,先查阅父类的描述,因为父类中定义的该体系中的共性内容)
聚集: has-a
聚合: 球员与球队的关系
组合: 一个对象可以包含另一个对象。这两个对象之间的关系称为组合(composition)。(手是人身体的一部分)
一个对象可以被几个其他聚集对象所拥有。如果一个对象只归属于一个聚集对象,那么它和聚集对象之间的关系就称为组合(composition)。
依赖(Dependency)关系是类与类之间的联接。依赖关系表示一个类依赖于另一个类的定义。例如,一个人(Person)可以买车(car)和房子(House),Person类依赖于Car类和House类的定义,因为Person类引用了Car和House。与关联不同的是,Person类里并没有Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中去的。一般而言,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。
关联(Association)关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。关联可以是双向的,也可以是单向的。在Java语言中,关联关系一般使用成员变量来实现。
聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便整体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。但是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分。
组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,组合关系是不能共享的。代表整体的对象需要负责保持部分对象和存活,在一些情况下将负责代表部分的对象湮灭掉。代表整体的对象可以将代表部分的对象传递给另一个对象,由后者负责此对象的生命周期。换言之,代表部分的对象在每一个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期。部分和整体的生命周期一样。
重写(覆盖)与重载
- 重载(overload):对于类的方法(包括从父类中继承的方法),方法名相同,参数列表不同的方法之间就构成了重载关系。
- 什么叫参数列表?参数列表又叫参数签名,指三样东西:参数的类型,参数的个数,参数的顺序。这三者只要有一个不同就叫做参数列表不同。
- 重载关系只能发生在同一个类中吗?非也。这时候你要深刻理解继承,要知道一个子类所拥有的成员除了自己显式写出来的以外,还有父类遗传下来的。所以子类中的某个方法和父类中继承下来的方法也可以发生重载的关系。
大家在使用的时候要紧扣定义,看方法之间是否是重载关系,不用管方法的修饰符和返回类型以及抛出的异常,只看方法名和参数列表。而且要记住,构造器也可以重载。
- 覆盖 (override):也叫重写,就是在当父类中的某些方法不能满足要求时,子类中改写父类的方法。当父类中的方法被覆盖了后,除非用super关键字,否则就无法再调用父类中的方法了。
发生覆盖的条件:
- “三同一不低” 子类和父类的方法名称,参数列表,返回类型必须完全相同,而且子类方法的访问修饰符的权限不能比父类低。
- 子类方法不能抛出比父类方法更多的异常。即子类方法所抛出的异常必须和父类方法所抛出的异常一致,或者是其子类,或者什么也不抛出;
- 被覆盖的方法不能是final类型的。因为final修饰的方法是无法覆盖的。
- 被覆盖的方法不能为private。否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
- 被覆盖的方法不能为static。所以如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足覆盖条件,那么会发生编译错误。反之亦然。即使父类和子类中的方法都是静态的,并且满足覆盖条件,但是仍然不会发生覆盖,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。(静态只能覆盖静态)
子类对象进行初始化时,父类构造函数也会进行初始化,原因在于,子类构造函数默认第一行有一条隐式语句super();
- 子类为什么要访问父类(所有子类构造函数中默认第一行都是super();)