Java方法+数组+面向对象基础

Java方法

  • 何为方法 
  1. 方法是解决一类问题的步骤的有序组合            eg    System.out.println()    类+对象+方法 
  2. 方法包含与类或对象中                             
  3. 方法在程序中被创建,在其他地方被引用

       设计方法时最好一个方法完成一个功能

输出1到1000 能被5整除的数的代码

  

  • 方法定义及调用 

修饰符 返回值类型 方法名(参数类型 参数名){

...

方法体

...

return 返回值;

}

调用方法:对象名.方法名(实参)

方法包含一个方法头和一个方法体,方法的所有部分有

修饰符告诉编译器如何调用该方法,定义了该方法的访问类型

返回值类型方法可能会返回值,return ValueType是方法返回值的数据类型,有些方法执行所需操作但无返回值,return ValueType是关键字void

return 0;      //有终止方法的作用

方法名:方法的实际名字,方法名和参数表共同构成方法签名

参数类型:1.形参:在调用时接受外界输入的数据2.实参:调用方法时实际传给方法的数据

方法体:方法体包含具体语句,定义该方法的功能

  • 方法重载

重载规则:1.方法名必须相同  2.参数列表中的个数或类型、参数排列顺序不同  3.方法的返回类型可以相同可以不同  4.仅仅返回类型不同不足以成为方法的重载

  • 命令行传参
  • 可变参数

1.Java支持传递同类型的可变参数给一个方法  2.在方法声明中,在指定参数类型后加一个省略号(…)  3.一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,如何普通的参数必须在它之前声明  

eg:

public class kebiancanshu {
    public static void main(String args[]) {
        //调用可变参数的方法

        printMax(54, 8, 4, 6.0);
        printMax(new double[]{1, 2, 3});
    }

    public static void printMax(double... numbers) {
        if (numbers.length ==0) {
            System.out.println("No argument passed");
            return;
        }
        double result = numbers[0];
        //排序
        for (int i = 1; i < numbers.length; i++) {
            if (numbers[i] > result) {
                result = numbers[i];
            }
            System.out.println("The max value is" + result);
        }
    }
}
  • 递归

1.递归就是A方法调用A方法

2.作用:把大型复杂问题层层转化为与原问题相似的规模较小的问题求解,用有限的语句来定义对象的无限集合

递归结构包括两部分:1.递归头:什么时候不调用自身方法,如果没有头,将陷入死循环  2.递归体:什么时候需要调用自身方法

public class digui {
    public static void main(String[] args) {
        System.out.println(f(5));
    }
    public static int f(int n){
        if(n==1){
            return 1;
        }else{
            return n*f(n-1);
        }
    }
}

利用递归求得了5的阶乘为120

Java数组

  • 数组概述

定义:

1.数组是相同类型数据的有序集合  2.数组描述的是相同类型的若干个数据,按照一定先后次序排列组合而成  3.其中的每一个数据称为一个数组元素,每个数组元素可以通过下标访问

基本特点:

1.长度确定,数组创建后大小不可修改   2.其元素类型必须相同   3.数组中的元素可以是任数据类型,包括基本类型和引用类型   4.数组变量属引用类型,数组可以看成对象,数组中每个元素相当于该对象的成员变量,数组本身就是变量,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的

数组边界:

下标的合法区间:[0,length-1] ,数组下标越界异常

  • 数组声明创建                                       

声明数组变量的语法:

dataType[] arrayrefVar;     //首选方法

dataType arrayRefVar[];    

Java语言使用new操作符来创建数组,语法如下:

dataType[] arrayRefVar = new dataType[arraySize];

1. 数组的元素是通过索引访问的,数组索引从0开始     2.获取数组长度:   arrays.length

 代码示例:           

public class shuzu {
    //数组的类型 数组的名字 = 数组的值
    public static void main(String[] args) {
        int[] nums;   // 声明一个数组       
        nums=new int[10];   //创建一个数组    
        nums[0]=1;          //声明和创建数组可以一起写:int[] nums=new int [10];    
        nums[1]=2;
        nums[2]=3;
        nums[3]=4;
        nums[4]=5;
        nums[5]=6;
        nums[6]=7;
        nums[7]=8;
        nums[8]=9;
        nums[9]=10;
        //计算所有元素的和
        int sum=0;
        //获取数组长度
        for(int i=0;i< nums.length;i++){
            sum=sum+nums[i];
        }
        System.out.println("总和为:"+sum);
    }
}

上面代码的声明和创建可以写为:   int[] nums = new int [10];

 数组声明时候并不存在,只有创建的时候存在

数组的三种初始化方式:

1.静态初始化(创建+赋值)

int [] a= {1,2,3};   //基本类型

Man[] mans = {new Man(1,1),new Ma(2,2)};    //引用类型

2.动态初始化(包含了默认初始化)

int[] a = new int[2];

a[0]=1;

a[2]=2;

3.默认初始化

数组是引用类型,它的元素相当于类的实例变量,当数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

  • 数组使用

代码展示(普通for循环):

public class p55shuzu {
    public static void main(String[] args) {
        int[] arrays={1,2,3,4,5};
        //打印全部的数组元素
        for (int i=0;i<arrays.length;i++){
            System.out.println(arrays[i]);
        }
        System.out.println("-------------");
        //计算所有元素的和
        int sum=0;
        for (int i=0;i<arrays.length;i++){
            sum=sum+arrays[i];
        }
        System.out.println("sum="+sum);
        System.out.println("--------------");
        //查找最大元素
        int max=arrays[0];
        for (int i=1;i<arrays.length;i++){
            if (arrays[i]>max){
                max=arrays[i];
            }
        }
        System.out.println("max:"+max);
    }
}

1.for-Each循环     

public class shuzu_forEach {
    public static void main(String[] args) {
        int[] arrays={1,2,3,4,5};
        //JDK1.5,无下标
        for (int array:arrays) {
            System.out.println(array);
        }
    }
}

2.数组作方法入参

3.数组作返回值

  • 多维数组

1.多维数组可以看成数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组

2.二维数组的定义

//二维数组a是一个2行5列的数组

int a[ ][ ] = new int[2][5];

示例代码:

public class erweishuzu {
    public static void main(String[] args) {
        //[4][2]
        /*
        1,2    array[0]
        2,3    array[1]
        3,4    array[2]
        4,5    array[3]
        */
        int [][] array={{1,2},{2,3},{3,4},{4,5}};
        for (int i = 0; i < array.length ; i++) {
            for (int j = 0; j < array[i].length ; j++) {
                System.out.println(array[i][j]);
            }

        }
    }

    //打印数组元素
    public static void printArray(int[] arrays) {
        for (int i = 0; i < arrays.length; i++) {
            System.out.println(arrays[i] + " ");
        }
    }
}
  • Arrays类

1.数组的工具类java.util.Array   2.API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行基本操作   3.查看JDK帮助文档   4.Arrays类中的方法都是static修饰的静态方法,使用时可直接用类名进行调用,而“不用”使用对象来调用(不用不是不能)   

Arrays类具有以下常用功能:

1.给数组赋值:通过fill方法  2.对数组排序:通过sort方法(按升序)  3.比较数组:通过equals方法比较数组元素值是否相同  4.查找数组元素:通过binarySearch方法对排序好的数组进行二分查找法操作

代码示例:

import java.util.Arrays;

public class Arraysyingyong {
    public static void main(String[] args) {
        int[]a = {1,28,7,95,452,8795};
       // System.out.println(a);   //[I@2d98a335
        //打印数组元素Arrays.tostring
       // System.out.println(Arrays.toString(a));
        Arrays.sort(a);  //数组进行排序
        System.out.println(Arrays.toString(a));
    }
}
  • 稀疏数组

1.当一个数组中大部分元素为0,或者为同一值时,可以用稀疏数组来保存该数组   2.稀疏数组的处理方式为记录数组一共有几行几列有多少个不同值,把具有不同值的元素和行列记在一个小规模的数组中

代码示例:

public static void main(String[] args) {
    //创建一个11*11的数组  0:没有棋子 1:黑子 2:白子
    int[][] array1 = new int[11][11];
    array1[1][2] = 1;
    array1[2][3] = 1;
    //输出原始的数组
    System.out.println("=====原始数组=====");
    for (int[] ints : array1) {
        for (int anInt : ints) {
            System.out.print(anInt+" ");
        }
        System.out.println();
    }



    //转换为稀疏数组存储
    System.out.println("=====稀疏数组=====");
    //1. 获取有效值的个数
    int sum = 0;
    for (int i = 0; i < array1.length; i++) {
        for (int j = 0; j < array1[i].length; j++) {
            if(array1[i][j]!=0)
                sum++;
        }
    }
    System.out.println("有效值个数为" + sum);
    //2.创建一个稀疏矩阵
    int[][] array2 = new int[sum+1][3];
    array2[0][0] = 11;
    array2[0][1] = 11;
    array2[0][2] = sum;
    //3. 遍历二维数组,将非零的值存放在稀疏数组中。
    int count = 0;
    for (int i = 0; i < array1.length; i++) {
        for (int j = 0; j < array1[i].length; j++) {
            if(array1[i][j]!=0)
            {
                count++;
                array2[count][0] = i;
                array2[count][1] = j;
                array2[count][2] = array1[i][j];
            }
        }
    }
    //输出稀疏矩阵
    for (int i = 0; i < array2.length; i++) {
        System.out.println(array2[i][0]+" "+array2[i][1]+" "+array2[i][2]);
    }



    //转化为原始数组
    System.out.println("=====还原数组=====");
    //1.读取稀疏数组
    int[][] array3 = new int[array2[0][0]][array2[0][1]];
    //2.给其中的元素还原它的值
    for (int i = 1; i < array2.length; i++) {
        array3[array2[i][0]][array2[i][1]] = array2[i][2];
    }
    //输出还原的数组
    for (int[] ints : array3) {
        for (int anInt : ints) {
            System.out.print(anInt+" ");
        }
        System.out.println();
    }
}

冒泡排序 

  • 两层循环,外层冒泡轮数,里层依次比较

代码示例:

     //冒泡排序(时间复杂度为O(n²))
    //1.比较数组中两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
   //2.每一轮比较,都至少会产生出一个最大,或者最小的数字;
  //3.下一轮则可以少一次比较!
 //4.依次循环,直到结束!
public static int[] sort(int[] nums){
    //轮数,五个数依次确定四个最小值即可,所以四轮即可
    boolean flag = true; //当某一轮比较没有发生改变,即已经有序,则可以直接返回
    for (int i = 0; i < nums.length - 1; i++) {
        //从前往后依次顺序相邻比较,第i轮已经确定i个最大值
        flag = false;
        for (int j = 0; j < nums.length - 1 - i; j++) { 
            if (nums[j] > nums[j+1]) {
                int temp = nums[j+1];
                nums[j + 1] = nums[j];
                nums[j] = temp;
            }
        }
        if(flag)
        {
            return nums;
        }
        
    }
    return nums;
}

Java面向对象编程

  • 初识面向对象

  1. 步骤清晰简单,第一步做什么,第二步做什么,适合处理一些简单问题

分类的思维模式,思考问题首先会解决问题需要哪些分类,最后对分类下的细节进行面向过程的思索

  1. 面向对象适合处理复制的问题,适合处理需要多人协作的问题
  2. 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作仍然需要面向对象的思路处理
  3. 面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据
  4. 三大特性:封装、继承、多态
  • 类与对象的创建

  1. 类是一种抽象的数据类型,它是某一类事物整体描述,但不能代表某一个具体的事物
  2. 对象是抽象概念的具体实例
  3. 创建和初始化对象
  4. 使用new关键字创建对象,用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
  5. 类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。并且构造器有以下两个特点:
    必须和类的名字相同
    必须没有返回类型,也不能写void

示例代码:

//类的定义
//Person类
public class Person {
    //属性: 字段
    String name;//默认null
    int age;//默认0

    //构造器
    Person(){

    }
    Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    //方法
    public void study(){
        System.out.println(this.name + "在学习");
    }
}
//一个测试类
//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类:抽象的,实例化
        //类实例化后会返回一个自己的对象!
        //xiaohong对象就是一个Student类的具体实例!

        Person xiaohong = new Person();
        Person xiaoming = new Person("xiaoming",3);

        System.out.println(xiaohong.name);//null
        System.out.println(xiaohong.age);//null

        xiaohong.name = "xiaohong";
        xiaohong.age = 18;

        System.out.println(xiaohong.name);//xiaohong
        System.out.println(xiaohong.age);//18

        xiaoming.study();//调用方法

    }
}
  • 构造器
  1. 和类名相同
  2. 没有返回值
  3. 作用:new本质在调用构造方法;初始化对象的值
  4. 注意点:定义有参构造后,如果想使用无参构造,显示的定义一个无参的构造
  5. 代码示例
//Person类
public class Person {
    //属性: 字段
    String name;//默认null
    int age;

    //构造器
    //一个类即时什么也没写,它也会存在一个隐式的构造器方法(无参,默认值)

    //增加构造器的快捷键Alt+insert
    //无参构造器,如果一个构造器都没有,这就是隐式的构造器方法
    Person(){
    }
    //有参构造器:一旦定义了有参构造,再要使用无参构造就得显式定义
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }

}
//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类:抽象的,实例化
        //类实例化后会返回一个自己的对象!
        //xiaohong对象就是一个Student类的具体实例!

        Person xiaohong = new Person();
        Person xiaoming = new Person("xiaoming",3);

        System.out.println(xiaoming.name);//xiaoming
        System.out.println(xiaoming.age);//3
    }
}

面向对象的三大特征

1.封装

定义:类的内部数据操作细节自己完成,不许外部干涉,仅暴露少量方法给外部使用

优点:1.提高程序安全性,保护数据  2.隐藏代码的实现细节  3.统一接口  4.系统的可维护性增加

代码示例:

//类 private:私有
public class Student {
    //属性私有
    private String name;//名字
    private int id;//学号
    private char sex;//性别
    private int age;//年龄

    //提供一些可以操作这个属性的方法
    //提供一些public的get、set方法
    //get 获得这个数据
    public String getName() {
        return name;
    }
    //set 设置这个数据
    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age<0||age>120){//不合法的输入
            this.age = 3;
        }else{
            this.age = age;
        }
    }
}

2.继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

extends的意思是“扩展”,子类是父类的扩展

JAVA中类只有单继承,一个儿子只能有一个爸爸,但一个爸爸可以有多个儿子

继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等

继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

子类和父类之间,从意义上讲应该具有"is a"的关系

object类

  • super

注意点:1.super调用父类的构造方法,必须在构造方法的第一个  2.super 必须只能出现在子类的方法或者构造方法中  3.super和 this不能同时调用构造方法(因为super();和this();都必须在第一行)

与this的不同点:1代表的对象不同(this:本身调用者这个对象; super:代表父类对象的)    2.应用前提的不同(this:没有继承也可以使用; super:只能在继承条件才可以使用)   3构造方法的不同(this();本类的构造; super():父类的构造)

方法重写

final修饰的类不能被继承

代码示例:

//父类
public class Person {

    protected String name = "father";

    Person(){
        System.out.println("Person无参构造执行了");
    }


    public void print(){
        System.out.println("Person");
    }
    private void printPrivate(){
        System.out.println("PersonPrivate");
    }


}
// Student: 派生类,子类
public class Student extends Person {

    private String name = "son";

    Student(){
        //隐藏代码,如果未显式调用父类构造器,默认调用父类无参构造
        super();//调用父类构造器或子类的其他构造器,必须在构造器的第一行
        System.out.println("Student无参构造执行了");
    }
    Student(String name){
        this();
        this.name = name;
    }


    public void print(){
        System.out.println("Student");
    }

    public void testPrint(){
        print();
        this.print();
        super.print();
        //super.printPrivate();//父类私有方法无法访问
    }
    public void testName(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}
//执行类
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.testName("name");
        student.testPrint();
    }
}

方法重写

前提:需要有继承关系,子类重写父类的方法

特点:1.方法名必须相同   2.参数列表列表必须相同   3.修饰符:范围可以扩大但不能缩小(Public>Protected>Default>Private ) 4.抛出的异常:范围,可以被缩小,但不能扩大(Exception(大) -->ClassNotFoundException)

快捷键:Alt+Insert;  override

不能重写的方法:static 方法,属于类,不属于实例       final 常量      private方法

代码示例:

//父类
public class B {
    public static void test(){
        System.out.println("B->test()");
    }
    public void test1(){
        System.out.println("B->test1()");
    }
}

//子类
//重写都是方法的重写,和属性无关
public class A extends B{
    public static void test(){
        System.out.println("A->test()");
    }

    //override:重写
    @Override //注解:有功能的注释
    public void test1() {
        System.out.println("A->test1()");
    }
}
//执行类
public class Application {
    //静态方法和非静态方法区别很大
    public static void main(String[] args) {

        //静态方法:方法的调用只和左边有关,即定义的数据类型
        A a = new A();
        a.test();//A
        //父类的引用指向A
        B b = new A();
        b.test();//B

        //非静态方法:子类重写了父类的方法
        a.test1();//A
        b.test1();//A

    }
}
  • 多态

  1. 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
  2. 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
  3. 多态存在的条件(有继承关系;  子类重写父类方法父类;   引用指向子类对象)
  4. 多态注意事项:

    (1)多态是方法的多态,属性没有多态  (2)父类和子类,有联系,不然会报错类型转换异常! CLassCastException !  (3)存在条件:继承关系,方法需要重写,父类引用指向子类对象
  5. instanceof   (类型转换)   引用类型,判断一个对象是什么类型

代码示例:

public class Application {
    public static void main(String[] args) {
        //Object > String
        //Object > Person > Student
        //Object > Person > Teacher
        Object object = new Student();
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//true
        System.out.println(object instanceof String);//false
        System.out.println("======================");

        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(person instanceof String);//编译报错
        System.out.println("======================");

        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);//编译报错
        //System.out.println(person instanceof String);//编译报错
        System.out.println("======================");

        /*
            编译能否通过看左边。运行结果看右边
         */
    }
}
  • 抽象类

  1. abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
  2. 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
  3. 抽象类,不能通过使用new关键字来创建对象,它是用来让子类继承的
  4. 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的
  5. 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类

代码示例:

//abstract 抽象类
//类只能单继承,但是接口可以多继承
public abstract class Action {
    //约束~ 有人帮我们实现~
    //abstract ,抽象方法,只有方法名字,没有方法的实现
    public abstract void doSomething();
    public void hello(){

    }

    public Action() {
        System.out.println("抽象类构造器");
    }
    /*
    特点:
    1. 不能new这个抽象类,只能靠子类去实现它;约束
    2. 抽象类中可以写普通方法
    3. 抽象方法必须在抽象类中
    抽象的抽象
    思考题:
    1. 不能new?存在构造器吗 存在
    2. 抽象类的意义 提高开发效率
     */
}
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法。除非子类也是抽象类
public class A extends Action{
    public A() {
        System.out.println("子类构造器");
    }

    @Override
    public void doSomething() {

    }
}
public class Application {
    public static void main(String[] args) {
        A a = new A();
    }
}

运行结果:    抽象类构造器

                      子类构造器

  • 接口

  1. 普通类:只有具体实现

  2. 抽象类:具体实现和规范(抽象方法)都有
  3. 接口:只有规范!自己无法写方法~专业的约束!约束和实现分离:面向接口编程
  4. 接口就是规范,定义的是一组规则,体现了现实世界中”如果你是…则必须能…”的思想。如果你是天使,则必须能飞     eg:如果你是汽车,则必须能跑
  5. 接口的本质是契约,就像我们人间的法律一样,制定好后大家都遵守
  6. 面向对象的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c等),就是因为设计模式所研究的,实际上就是如何合理的去抽象
  7. 声明类的关键字是class,声明接口的关键字是interface
  8. 作用:(1)约束;  定义一些方法,让不同的人实现; (2)  public abstract;  (3)  (4)public static final;  (5) 接口不能被实例化,接口中没有构造方法;                  (6)implements可以实现多个接口    (7)必须要重写接口中的方法   

代码示例  

//接口1
public interface UserService {
    //接口中的所有成员都是常量 public static final
    public static final int age = 99;
    String name = "name";
    //接口中的所有定义其实都是抽象 public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);

    void timer();

}
//接口2
public interface TimeService {
    int age = 2;
    void timer();
}
//抽象类 : extends 单继承
//类 可以实现接口 implements接口
//实现接口的类,就需要重写接口中的方法
//利用接口实现伪多继承

//实现类
public class UserServiceImpl implements UserService,TimeService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {
        System.out.println("timer");
        System.out.println(TimeService.age);
        System.out.println(UserService.age);
        //System.out.println(age);//编译报错
        System.out.println(name);
    }
}
//测试类
public class App{
    public static void main(String[] args) {
        TimeService time = new UserServiceImpl();
        time.timer();
        UserService user = new UserServiceImpl();
        user.timer();
    }
}
  • 内部类

内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了

// 外部类
class Outer{
  // 内部类
  class Inner{
    // 也会生成class文件
  }
}
  1. 成员内部类

    (1)在类的内部定义,与实例变量、实例方法同级别的类   (2)外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象  (3)当外部类、内部类存在重名属性时,会优先访问内部类属性  (4)成员内部类里不能定义静态成员(static)、可以包含静态常量(static final)

public class Outer {
    //实例变量
    private String name = "张三";
    private int age = 20;
    //内部类
    class Inner{
        private String address = "北京";
        private String phone = "110";
        private String name = "李四";
        
        //private static String country = ""; 不能包含静态成员
        private static final String country1 ="中国";//但是能包含静态常量

        //方法
        public void show(){

            //打印外部类属性 此时有重名属性name
            System.out.println(Outer.this.name);// 张三
            System.out.println(age);

            //打印内部类中的属性
            System.out.println(name);//李四
            System.out.println(this.name);// 李四
            System.out.println(address);
            System.out.println(phone);
        }
    }
}

   

public class Test {
    public static void main(String[] args) {
        // 创建外部类对象
        Outer outer = new Outer();
        // 创建内部类对象
        Outer.Inner inner1 = outer.new Inner();
        inner1.show();

        //一步到位
        Outer.Inner inner2 = new Outer().new Inner();
        inner2.show();
    }
}

    2.静态内部类

      不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员

// 外部类
public class Outer{
  //实例变量
  private String name = "xxx";
  private int age = 20;
  
  // 静态内部类,级别和外部类相同
  static class Inner{
    private String address = "上海";
    private String phone = "111";
    // 静态成员
    private static int count = 1000;
    
    //方法
    public void show(){
      // 调用外部类的属性
      // 1. 先创建外部类对象
      Outer outer = new Outer();
      // 2. 调用外部类对象的属性
      System.out.println(outer.name);
      System.out.println(outer.age);
      // 调用静态内部类的属性和方法
      System.out.println(address);
      System.out.println(phone);
      // 调用静态内部类的静态属性
      System.out.println(count);
      System.out.println(Inner.count);
    }
  }
}
// 测试类
public class Test{
  public static void main(String[] args){
    // 直接创建静态内部类对象
    Outer.Inner inner = new Outer.Inner();
                     
    inner.show();
    
    Inner inner1 = new Inner();
  }
}

    3.局部内部类

(1)定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

(2)局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final

(3)限制类的使用范围,只能在当前方法中使用

// 外部类
public class Outer{
  //实例变量
  private String name = "刘德华";
  private int age = 35;
  
  //方法
  public void show(){
    // 定义局部变量
    String address = "sz";
    
    // 局部内部类:注意不能加任何访问修饰符
    class Inner{
      private String phone = "11234";
      private String email = "ldh@qq.com";
      //private static String country = ""; 不能包含静态成员
      private static final String country1 ="中国";//但是能包含静态常量

      public void show2(){
        // 访问外部类的属性
        System.out.println(name); // 相当于 Outer.this.name
        System.out.println(age);
        // 访问内部类的属性
        System.out.println(this.phone);
        System.out.println(this.email);
        
        // 访问局部变量 jdk1.7要求必须常量final、jdk1.8自动添加final
        System.out.println(address);
      }
    }
    // 创建局部内部类对象
    Inner inner = new Inner();
    inner.show2();
    //address = "123"; 因为局部内部类访问了address,所以address默认为final常量,后面不能进行更改
  }
}
// 测试类
public class Test{
  public static void main(String[] args){
    // 创建外部类对象
    Outer outer = new Outer();
                     
    outer.show();
  }
}

    4.匿名内部类

(1)没有类名的局部内部类(一切特征都与局部内部类相同)

(2)必须继承一个父类或者实现一个接口

  (3)定义类、实现类、创建对象的语法合并,只能创建一个该类的对象

  (4)优点:减少代码量

  (5)缺点:可读性较差

//接口
public interface Usb {
    public void service();
}
//测试类
public class Test {
    public static void main(String[] args) {
        // 使用匿名内部类优化(相当于创建了一个局部内部类)
        Usb usb = new Usb(){ // Usb为一个接口
            @Override
            public void service(){
                System.out.println("连接电脑成功,开始工作");
            }
        };
        usb.service();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值