排序算法之选择排序
选择排序的思想:第一个数和后面的数依次进行比较,遇到比它小的就交换位置,让这个更小的数和后面的数继续比较,第一次完之后得出一个最小的数,依次这样比较。
自定义一个数组,进行选择排序:
public class Test1 {
public static void main(String[] args) {
int[] arr = {12,32,20,45,67,90,72} ;
printArray(arr);
switchSort(arr);
printArray(arr);
}
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]+", ");
}
}
}
public static void switchSort(int[] arr) {
for(int i=0;i<arr.length-1;i++) {
for(int j = i+1 ;j<arr.length;j++) {
if(arr[j]<arr[i]) {
int temp = arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
}
}
面向对象的三大特征之继承
继承:定义一个独立的类,将其他类中的共性方法抽取到该类中,让这个独立的类和其他类产生一种关系:“继承”关系
继承的好处:1) 提高了代码的复用性
2) 提高了代码的维护性
3) 类和类产生的这种关系,是多态的前提条件
继承的特点:在Java语言中,类和类之间只支持单继承,不支持多继承,但支持多层继承
继承中的注意事项:1) 子类继承父类,只能继承父类中所有非私有的成员,如果要访问,可以通过公共的访问方法来访问;
2) 子类继承父类,不能继承父类的构造方法,但是可以通过关键字来访问(super())
3) 不要为了部分功能使用继承(开发的原则:低耦合,高内聚)
继承中的成员关系:成员变量、成员方法、构造方法
1.成员变量:两种情况:
子类继承父类,如果子类中的成员变量和父类中的成员变量名称不一致,分别访问即可;
子类继承父类,如果子类中的成员变量和父类中的成员变量名称一致,执行流程如下:
1) 先在子类的局部位置中找,如果找到了,就使用;
2) 如果找不到,就在子类的成员位置中找,如果找到了,就使用;
3) 如果找不到,就在父类的成员位置中找,如果找到了,就使用;
4) 如果找不到,程序就会报错。
2.成员方法:两种情况:
子类继承父类,如果子类中成员方法和父类中的成员方法名称不一致,分别调用即可;
子类继承父类,如果子类中的成员方法和父类中的成员方法名称一致,执行流程如下:
1) 先在子类的成员位置中找,如果找到了,就使用它;
2) 如果找不到,就在父类的成员位置中找,如果找到了,就使用它;
3) 如果找不到,程序就会报错。
3.构造方法:
子类是不能继承父类的构造方法的,但是通过super()来访问父类的构造方法,在继承中,子类的构造方法(有参或者无参)默认访问父类的无参构造方法。相当于子类的构造方法,第一句都隐藏了super()。
super():如果在子类的构造方法中显示给出了,必须写在第一句,否则可能出现子类初始化多次。
子类的所有构造方法默认访问父类的无参构造方法,如果父类没有提供无参构造方法,程序就会报错,解决方法如下:
1) 手动给出父类的无参构造方法
2) 手动不提供无参构造方法的解决方法:
(1)间接的通过super(xx)来访问父类的有参构造方法
(2)通过this()访问子类的无参构造方法,然后通过子类的无参构造方法里面的super(xx)间接访问父类的有参构造方法
继承中的方法重写:在继承关系中,子类出现了和父类一模一样的方法,这个时候子类会将父类的方法覆盖掉,将这种现象成为:方法重写。有时候,不能将父类的功能覆盖掉,Java提供了一个关键字:final(状态修饰符)
final的特点:1) 修饰类:该类不能被继承
2) 修饰成员变量:此时变量就是常量
3) 修饰成员方法:该方法不能被重写
面向对象的三大特征之多态
多态:一个事物在不同时刻的体现
多态的前提条件:1) 必须有继承关系
2) 方法重写
3)父类引用指向子类对象
向上转型:父类名 对象名 = new 子类名();
多态的成员访问特点:成员变量、成员方法、静态成员方法、构造方法
成员变量:编译看左边,运行看左边
成员方法:编译看左边,运行看右边
静态成员方法:编译看左边,运行看左边
构造方法:分层初始化:先让父类初始化,然后是子类初始化
多态的好处:1) 提高了代码的复用性(由继承来保证)
2) 提高了代码的扩展性(由多态来保证)
多态的弊端:不能访问子类的特有功能
解决方法:1) 创建子类的具体对象来访问子类的特有功能
2) 向下转型:将父类的引用强转为子类的引用(前提必须有向上转型)
格式:子类名 对象名 = (子类名)父类的引用;
抽象类
抽象类:如果一个类中存在一个功能,仅仅方法声明,没有方法体,需要将该类定义抽象类
特点:1) 如果一个类中有抽象方法,那么该类是抽象类;如果一个类是抽象类,该类中不一定存在抽象方法
2) 抽象类不能实例化(不能创建对象)
3) 抽象类需要通过子类进行初始化:抽象类多态
4) 抽象方法的格式:没有方法体的方法
格式:权限修饰符 abstract 返回值类型 方法名(形式参数);
5) 抽象类必须强制子类完成的事情:将抽象类中所有的方法重写
抽象类的成员特点:成员变量、成员方法、构造方法
1)成员变量:可以是变量,也可以是常量
2)成员方法:可以是抽象类方法,也可以是非抽象类方法
3)构造方法:存在有参或者无参构造方法
接口
接口:体现的是事物的一种扩展性功能(本身不具备,经过一些学习才能具备的功能)
接口的表示:interface 接口名{}
接口中的注意事项:1) 接口中只能定义抽象方法
2) 接口不能实例化
3) 接口的实例化:通过接口的子实现类来进行实例化
格式:接口名 对象名 = new 子实现类名();
4) 接口的子实现类:子实现类研究的都是具体类,因为具体的子实现类可以实例化
接口中成员特点:成员方法、成员变量、构造方法
1) 成员变量:只能是常量,存在默认的修饰符:public static final
2) 成员方法:只能是抽象方法,存在默认的修饰符:public abstract
3) 构造方法:不存在构造方法
抽象类和接口之间的区别
1.成员的区别:成员变量:抽象类:可以是常量也可以是变量
接口:只能是常量
成员方法:抽象类:可以是抽象方法也可以是非抽象方法
接口:只能是抽象方法
构造方法:抽象类:有参或者无参构造方法
接口:没有构造方法
2.关系的区别:类与类之间:继承关系
类与接口之间:实现关系
接口与接口之间:继承关系
3.设计理念的区别:抽象类:继承关系,体现一种"is a"的关系
接口:实现关系,体现一种"like a"的关系
内部类
内部类:就是在一个类中定义另一个类,在A类中定义一个B类,将B类称为A类的内部类,将A类称为B类的外部类。
内部类可以访问外部类的成员,包括私有的
外部类的成员要访问内部类的成员,要创建对象来访问
内部类的分类:成员内部类、局部内部类
成员内部类:在外部类的成员位置定义的类
局部内部类:在外部类的成员方法中定义的一个类
在测试类中访问非静态内部类的成员:访问方式:
外部类名.内部类名 对象名 = 外部类对象().内部类对象();
在测试类中访问静态成员内部类的成员方法:访问方式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
匿名内部类
格式:
new 类名/接口名(){
重写方法;
};
匿名内部类的好处:省去了繁杂的代码,不需要定义里面的子类或者子实现类
匿名内部类的本质:继承该类或者是实现了该接口的子类对象
给接口的内部类起名字:创建接口对象----->通过接口匿名内部类
接口名 对象名 = new 接口名(){
重写接口中抽象方法;
};
class Outer{
public void method() {
Inner i = new Inner() {
@Override
public void show() {
System.out.println("show Inner");
}
@Override
public void show2() {
System.out.println("show2 Inner");
}
};
i.show();
i.show2();
}
}
public class InnerClassDemo6 {
public static void main(String[] args) {
Outer6 outer = new Outer6() ;
outer.method();
}
}