一、内部类
-
在Java中,在类中可以定义一个类,内部类
在类A中,定义一个类B,
类B称为类A的"内部类"
类A称为类B的"外部类"内部类的成员是可以访问外部类的成员,包括私有!
外部类的成员方法访问成员内部类的成员方法时候,必须创建内部类对象访问
举例:
//定义一个外部类
class Outer{
public int num = 10 ;
private int num2 =100 ;
//定义一个内部类
class Inner{
//成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
//外部类的成员方法
public void method(){
//show() ;
Inner inner = new Inner() ;
inner.show();
}
}
//测试类
public class OuterDemo {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer() ;
outer.method();
}
}
- 内部类的分类:
成员内部类:
在一个类的成员位置中定义的类
局部内部类:
在一个类的局部位置中定义的类(方法中)
//外部类
class Outer2{
//成员变量
private int num = 10 ;
//成员位置
//成员内部类
/* class Inner2{
}*/
//外部类的成员方法
public void method(){
//局部位置
//局部内部类
class Inner{
public void show(){
System.out.println(num);
}
}
}
}
public class OuterDemo2 {
public static void main(String[] args) {
}
}
-
成员内部类:
在一个类的成员位置中定义的类需求:测试类中直接访问成员内部类的成员方法: 访问的方式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象; 前提条件:这个成员内部类---是一个非静态的成员内部类!
举例:
//外部类
class Outer3{
//成员变量
private int num = 100 ;
private static int num2 = 20 ;
//定义成员内部类
class Inner3{
//成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
}
//测试类
public class OuterDemo3 {
public static void main(String[] args) {
//要访问成员内部类Inner3里面的show方法
// 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer3.Inner3 oi = new Outer3().new Inner3() ;
oi.show() ;
}
}
-
关于成员内部类的修饰符
成员内部类可以被private修饰—保证数据的安全性:让外界不能new 来访问!伪代码 需求:人 有身体,身体内有心脏! 身体---Body 外部类 class Body{ //心脏:heart 作为的内部类 private class Heart{// 成员内部类---加入private //成员方法 public void heartOperator(){ System.out.println("心脏搭桥手术...") ; } } public void method(){ //里面判断 if("如果你是外科医生"){ Heart heart = new Heart() ; heart.heartOperator() ; } } } //测试类: 访问Body类中Heart的heartOperator方法 外部类名.内部类名 对象名 = 外部类对象.内部类对象; 但是此时这个类private,这种方式不能访问--- 可以保证数据的安全性
成员内部类也可以被static修饰:
它里面的成员访问外部类的成员特点:此时外部类的成员必须都是静态的
外界类中要访问静态的成员内部类的成员方法:
需要将静态的成员内部类---->看成是外部类的静态成员
外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
非静态的成员内部类中,不能存在静态的成员—“冲突了”
举例:
//外部类
class Outer4{
//一个非静态的变量
private int num = 20 ;
//一个静态变量
public static int num2 = 30 ;
//成员内部类----->加入static修饰
static class Inner4{
//定义一个非静态的成员方法
public void show(){
// System.out.println(num);
System.out.println(num2);
}
//定义一个静态的成员方法show2
public static void show2(){
// System.out.println(num);
System.out.println(num2);
}
}
}
//测试类
public class OuterDemo4 {
public static void main(String[] args) {
//需求:要访问静态的成员内部类中的show,show2方法?
//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
// Outer4.Inner4 oi = new Outer4().new Inner4() ;
//外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
Outer4.Inner4 oi = new Outer4.Inner4() ;
oi.show() ;
oi.show2() ;
System.out.println("----------------------------");
//show2()方法的另一种方式:类名访问: 静态的方法
//把静态的成员内部类----> 就是外部类的静态成员
Outer4.Inner4.show2() ;
}
}
-
局部内部类:在外部类的成员方法中定义的类,(非静态的)
直接可以访问外部类的包括私有局部内部类访问局部变量的时候: 此时局部变量已经是常量了:被final修饰 jdk7以前:如果局部变量不显示的添加final关键字,编译报错! jdk8版本,对当前局部内部类访问局部变量---此时变量在内存中已经优化为final了,不需要显示添加这个关键字! 为什么局部变量:是一个常量呢? 当前外部类对象调用外部类的成员方法时候,num2随着method的方法调用而存在 随着method调用完毕,应该消失掉了;但是局部内部类的成员方法还在使用这个num2,所以 JVM进行了优化,JDK8以后 这个变量自动回加入final定义,所以这个必须是一个常量,那么内部类才能使用它!
举例:
//定义一个外部类
class Outer5{
private int num = 20 ;
public void method(){
//局部变量
int num2 = 50 ;// 常量 --->jdk8以后 :局部内部类访问这个局部变量,可以不书写final,隐藏的!
//局部内部类
class Inner5{
public void show(){
System.out.println(num);//Outer5.this.num:外部类的this限定
System.out.println(num2); //常驻内存--"常量池中"
}
}
Inner5 inner5 = new Inner5() ;
inner5.show();
}
}
public class OuterDemo5 {
public static void main(String[] args) {
//访问Inner5中的show
//创建外部类对象.调用method
Outer5 outer5 = new Outer5() ;
outer5.method();
}
}
练习:
看程序,写结果
* 分别输出:30,20,10
*/
class Outer6{
public int num = 10 ;
//成员内部类
class Inner6{
int num = 20 ;
public void show(){
int num = 30 ;
//补全代码
System.out.println(num); // 就近原则
System.out.println(this.num); //限定当前类来访问
//System.out.println(new Outer6().num); //通过外部类对象访问变量:访问外部类成员变量
//外部类的this限定
System.out.println(Outer6.this.num);
}
}
}
public class OuterDemo6 {
public static void main(String[] args) {
Outer6.Inner6 oi = new Outer6().new Inner6() ;
oi.show();
}
}
二、选择排序
- 数组高级排序—选择排序
思想:
使用0角标对应的元素依次和后面的元素比较,小的值往前放,依次这样比较:
下一次1角标对应的元素和后面元素比较…
//测试类
public class ArraySortTest {
// private static Student s = null ;
public static void main(String[] args) {
//创建一个数组,静态初始化
int[] arr = {24,69,87,56,13} ;
System.out.println("选择排序前:");
printArray(arr);
//选择排序:
//第一次比较:
//定义一个变量:x 表示的前面的元素的角标值
/* int x = 0 ; //角标
//将后面的元素从数组遍历---for循环
//从角标1开始
for(int y = x+1 ; y < arr.length; y++ ){
//判断
//如果后面的元素比前面元素进行互换
if(arr[y] < arr[x]){
//中间变量
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第一次排序后:");
printArray(arr);
System.out.println("-------------------------------------------------");
//第二次比较
x = 1 ;
//继续后面角标对应的元素进行比较
for(int y = x + 1 ;y < arr.length ; y ++){
//继续判断
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第二次比较后:");
printArray(arr);
System.out.println("-------------------------------------------------");
//第三次比较
x = 2 ;
for(int y = x +1 ; y < arr.length ; y ++){
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第三次比较后:");
printArray(arr);
System.out.println("-------------------------------------------------");
//第四次比较
x = 3;
for(int y = x +1 ; y < arr.length ; y ++){
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第四次比较后:");
printArray(arr);
*/
//上面的代码冗余度高,改进
//比较4次
/*for(int x = 0 ; x < 4 ; x++){//比较次数
for(int y = x + 1 ; y < arr.length ; y ++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
System.out.println("排序后:");
printArray(arr);*/
System.out.println("---------------------------------");
//比较次数数数组长度-1次
for(int x = 0 ; x < arr.length-1 ; x++){//比较次数
for(int y = x + 1 ; y < arr.length ; y ++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
System.out.println("排序后:");
printArray(arr);
System.out.println("---------------------------------");
//快速抽取方法快捷键: ctrl+alt+M
//ctrl+alt+f:快速抽取到成员变量
//ctrl+alt+v:将某个变量:局部变量
// s = new Student();
selectSort(arr);
printArray(arr);
}
//定义一个选择排序功能
public static void selectSort(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 temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
//定义一个遍历的功能
public static void printArray(int[] arr){
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if(i == arr.length-1){
System.out.println(arr[i]+"]");
}else{
System.out.print(arr[i]+", ");
}
}
}
}