排序算法之选择排序
选择排序:
使用0索引的元素依次和后面索引的元素比较,小的往前放
第一次比较完毕,最小值出现在最小索引处!
50 62 49 38 81
0 1 2 3 4
public class ArrayDemo1 {
public static void main(String[] args) {
//定义一个数组
int[]arr= {50,62,49,38,81};
printArray(arr);
switchSort(arr);
}
//选择排序
public static void switchSort(int[]arr) {
for(int x=0;x<arr.length-1;x++) {//比较次数
for(int y=x+1;y<arr.length;y++) {
if(arr[y] <arr[x]) {
int teep=arr [x];
arr[x]=arr[y];
arr[y]=teep;
}
}
}
}
//遍历
public static void printArray(int[]arr) {
System.out.print("[");
for(int x=0; x<arr.length;x++) {
if(x==arr.length-1) {
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
}
继承
概念:需要定义独立的类,将其他类的共性内容抽取到该独立的类中,让其他类和这个独立类的产生一种关系: "继承"关系.
继承的好处:
* 1)提供了代码的复用性 (代码结构清晰)
* 2)提供了了代码的维护性
* 3)类和类产生的这种"继承关系",是多态的前提条件
* 开发的原则:
* 低耦合,高内聚
继承的特点:
*
* 1)在Java语言中,类和类之间只支持单继承,不支持多继承
*
* 2)虽然不支持多继承,但是类与类之间是可以多层继承的!
子类继承父类,如果子类中的成员变量名称和父类的成员变量名称一致的情况:
*
* 执行流程:
* 1)现在子类的局部位置中找,如果找到了就使用它
* 2)如果局部位置中没有,在子类的成员位置中找,如果找到了,就使用!
* 3)如果找不到,就在父类的成员位置中找,如果找到了,就使用
* 4)如果还找不到,就报错了,说明访问了一个不存在的变量!
*
* 遵循:"就近原则"
继承中为什么,创建子类对象的时候,先执行父类的无参构造方法?
* 答: 因为可能要用到父类中的数据,所以要先让父类中的数据进行初始化(构造方法),
* 父类初始化完毕了,然后才执行子类的构造方法(子类数据初始化)---->分层初始化!
如果父类的无参构造方法没有提供,那么子类构造会出现什么情况?
* 子类的所有构造方法默认父类的无参构造方法,父类如果没有提供,就报错了!
*
* 如何解决呢?
* 1)手动给出父类的无参构造方法 (之前说在写一个标准类的时候,建议永远给出无参构造方法)
* 2)如果手动不提供无参构造方法,如何解决?
* 2.1)间接的通过super(xx)来访问父类的有参构造初始化!
* 2.2)通过this(),访问本类(子类)的无参构造方法,然后在通过子类的无参构造方法里面super(xx)
* 间接访问父类的有参;
*
多态
概念:一个事物在不同时刻的体现.如水在不同时刻下显示出不同状态(固液气).
多态的成员访问特点:
* Fu f = new Zi() ;
* 成员变量:
* 编译看左边,运行看左!
* (等号左边编译通过,说明Fu类存在这个变量;运行看左,访问的是Fu类的变量)
* 成员方法:(与成员变量,静态成员方法有区别)
* 编译看左边,运行看右!
* (等号左边编译通过,说明Fu类存在这个方法;运行看右,子类出现了和父类一模一样的方法声明:方法重写)
* 静态的成员方法:
* 编译看左,运行看左!(静态的算不上方法重写,跟类直接相关,随着类的加载而加载!)
*
* 构造方法:存在继承关系(还是分层初始化)
* 先让父类初始化,然后在是子类初始化!
多态的好处:
* 1)提高了代码的复用性(由继承来保证)
* 2)提高了代码的扩展性(由多态的来保证)
多态的弊端
*
* 不能访问子类的特有功能!
解决方案:方案1):创建子类的具体对象来访问子类的特有功能!
方案2):
向下转型: 将父类的引用强转为子类的引用! (前提必须有向上转型Fu f = new Zi() )
* 格式:
* Zi z = (Zi)f;
方法重写(override) :
*
* 在继承关系中,子类出现了和父类一模一样的方法,这时子类会将父类的该功能覆盖掉,将这种现象
*称为:方法重写.
为了让父类的功能不被子类覆盖:引出final关键字.
final:最终的,无法更改的(状态修饰符)
* 被final修饰的成员方法:该方法不能被子类重写!
抽象类
概念:在一个类中,如果该类中存在一个功能,仅仅方法声明,没有方法体(抽象方法),需要将该类定义抽象类.
抽象类的成员特点:
* 1)成员变量
* 即可定义一个常量,也可以定义为变量
* 2)成员方法:
* 既可以定义抽象方法,也可以定义非抽象方法
* 3)构造方法:
* 存在构造方法,既可以有参构造也可以是无参构造方法(作用:对数据进行初始化)
*
定义成员方法的时,abstract关键字不能和哪些关键字共用 ?
* 和final关键字冲突
* 和private关键字冲突
* 和static关键字冲突
*
* 能够和public或者protected权限修饰符使用!
接口
接口(interface):体现的是事物的一种扩展性功能.(本身不具备的).
接口不能实例化,如何实例化呢?
* 通过接口的子实现类来进行实例化!
* 格式:接口名 对象名 =new 子实现类名();
Love love=new Loveimpl();
* 接口和子实现类之间的关系:实现关系(implements)
接口 成员特点:
* 成员方法:
* 只能是抽象方法,存在默认的修饰符,public abstract
* 成员变量:
* 只能是常量.存在默认的修饰符:public static final
*
* 构造方法:
* 不存在构造方法!
内部类
内部类的分类:
* 成员内部类
* 在外部类的成员位置定义的类
* 局部内部类
* 在局部位置(外部类的成员方法中)定义的一个类
* 访问内部类的成员:
*访问方式:
*
* 外部类名.内部类名 对象名 = 外部类对象().内部类对象();
*
匿名内部类:
格式:
new 类名/接口名(){
重写方法();
};
匿名内部类 好处:
省去繁杂代码,不需要定义类里面的子类或者接口的子实现类,写法比较简单.
匿名内部类 本质:
继承该类或者实现了该接口的子类对象.
JDK7以前(包含JDK7),局部内部类访问局部变量,局部变量必须加入final修饰,否则报错!
* JDK7以后,局部变量会自动加上final,开发者不需要定义final关键字,为什么要加final?
*
* 原因:
* 1)局部变量的生命周期,随着方法调用而存在,随着方法调用完毕而消失,
*2)在当前外部类成员方法中,创建局部内部类对象,来访问里面的局部变量,堆内存不会立即被释放
//定义外部类
class Outer{
private int num=30;
//成员方法
public void method (){
//局部变量
final int num2=70;
//局部内部类
class Inter{
public void show(){
}
}
}
}
*3)继续使用这个局部变量,需要将这个变量定义为常量,常驻内存---->以便局部内部类对象对该局部变量的访问!