java基础2:this、static、final、abstract关键字、代码块、生成API工具包、继承、多态、方法重载和重写,抽象类、接口、常见异常、java权限修饰符、选择排序思想和程序和内部类

1.this关键字

this表示当前类对象的地址空间值的引用。就是说,this代表了new出来的对象

其最大作用就是解决了构造器中局部变量隐藏成员变量。即用this.变量名 = 变量名 区分。

2.static关键字

共享共用,用static修饰的变量或方法不隶属与任何一个对象私有,他只属于类,实际应用中

将公共属性用static修饰,用类名.变量名(方法名)调用

3.继承

概念:将多个类的共性内容抽取到一个独立的类中,然后这多个类和独立的这个类产生一种关系: 继承关系!

关键字:extends

书写格式:class Fu{}

​ class Zi extends Fu{}

继承的好处: 1)提高代码的维护性!

​ 2)提高代码的复用性!

​ 3)让类和类之间产生的关系,是"多态的前提条件"

java中继承的特点:只支持单继承,但可以多层继承。

//没有使用继承之前
    //学生类
/*class Student{
    //定义成员方法
    public void eat(){
        System.out.println("学习饿了,就需要吃饭...");
    }
    public void sleep(){
        System.out.println("学习累了,就需要休息...");
    }
}

 */

//工人类
/*class Worker{
    //定义成员方法
    public void eat(){
        System.out.println("敲代码敲了,就需要吃饭...");
    }
    public void sleep(){
        System.out.println("敲代码敲困了,就需要休息...");
    }
}*/


//使用继承的写法:
 //将Student类和Worker类的共性内容抽取到:Person类 人类
 class Person{
    public void eat(){
        System.out.println("饿了,就需要吃饭...");
    }
    public void sleep(){
        System.out.println("困了,就需要休息...");
    }
}

//将学生类和工人类:继承自Person

class Student extends  Person{}
class Worker extends  Person{}

//测试类
public class ExtendsDemo {
    public static void main(String[] args) {
        //测试
        Student s = new Student() ;
        s.eat() ;
        s.sleep();
        System.out.println("----------------------") ;
        Worker worker = new Worker();
        worker.eat();
        worker.sleep();
        System.out.println("=========================================");
        //加入的继承
        Student s2 = new Student() ;
        s2.eat();
        s2.sleep();
        Worker w2 = new Worker() ;
        w2.eat();
        w2.sleep();


    }
}

继承中如果子类与父类的成员们变量名称一致的情况下的访问规则?

1)先在子类的局部变位置中找,是否存在这个变量,如果存在就使用。

2)如果不存在,那么就在子类的成员变量位置中找,如果存在就使用。

3)如果不存在,就在父类的成员变量位置中找,如果存在就使用。

4)如果都不存在,则就报错,表明没有这个变量。

子类如何访问父类的构造方法?

子类的所有构造方法的第一句都是:super(); 是隐藏的默认的

子类的所有构造方法加间接访问父类的无参构造方法:需要让父类先进行初始化,因为子类中可能用到父类的数据(分成初始化)

如果父类没有无参构造方法,子类会如何?

子类将会全部报错,解决:1)可以通过手动给父类加上无参构造方法

​ 2)子类的所有构造方法第一句手动加上:super(xxx)调用父类的有参构造

​ 3)子类的所有有参构造方法的第一句加上:this()先访问本类的无参构造, 然后在本类无参构造的第一句加上:super(xxx)的构造方法,让父类进行 初始化。

什么时候使用继承

如果A类是B类的一种,或者B类是A类的一种,此时可使用extends完成继承关系

继承体现的是“is a”的关系,即A是B的一种,B是A

不要为了部分功能而去使用继承

4.代码块

概念:在Java当中用{}包裹起来的内容叫做代码块

分类:局部代码块:在方法定义中使用,即方法的方法体。作用:限定局部变量的生命周期。

​ 构造代码块:在类的成员位置(类中,方法体外),使用{}包裹起来。

​ 作用:给类中的一些成员进行初始化。

​ 静态代码块:在类的成员位置,但用static修饰,随着类的加载而加载,优先于对象存在。

​ 作用:后期通过static代码块可以进行(I/O流创建文件/JDBC(Java链接数据库驱 动))等操作

​ 优先级:静态代码块 > 构造代码块 > 局部代码块

//定义一个code类
class Code {
    //静态代码块
    static{
        int x = 1000;
        System.out.println(x);
    }

    //无参构造方法
    public Code(){
        System.out.println("code demo...");
    }
    //构造代码块
    {
        int x = 100 ;
        System.out.println(x);
    }

    {
        int y  = 200 ;
        System.out.println(y);
    }
    //有参构造方法
    public Code(String name){
        System.out.println("code demo"+name);
    }
    //静态代码块
    static{
        int y = 2000 ;
        System.out.println(y);
    }
}

//测试类
public class CodeDemo {
    public static void main(String[] args) {

        //定义一个变量
       // int a = 10 ;
      //  System.out.println(a);

        //定义一个局部代码块
        {
            int x = 20 ;
            System.out.println(x); //x的作用域就是在{}内有效
        }
       // System.out.println(x);

        //创建一个Code类对象
        Code code = new Code() ;
        System.out.println("-----------");
        Code code2 = new Code("hello") ;

    }
}

5.生成自己API工具包示例

/**
 * 这个类是针对数组操作的工具类,里面提供了数组的遍历,获取数组中的最大值,以及提供冒泡排序,
 * 以及查询数组中的某个元素的索引值的功能...
 *
 * @author  yang
 * @version  V1.0
 * */
public class ArrayTool {

    //工具类中一般构造方法私有化的:一般是不让外界直接去new(创建实例)
    private ArrayTool(){}

    //printArray是ArrayTool的成员方法

    //这个类中的所有的成员方法加入static
    /**
     * 这个功能是数组的遍历功能,最终遍历的结果形式为[元素1, 元素2, 元素3, ...]
     * @param arr 它是针对指定的数组进行遍历
     * */
    public static  void printArray(int[] arr){//ArrayDemo类的成员方法
        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]+", ");
            }
        }
    }

    /***
     * 这个功能是针对数组获取最大值
     * @param arr 在指定的数组中查询
     * @return 最终返回的就是数组中的最大值
     */
    public static int getMax(int[] arr){
        //参照物
        int max = arr[0] ;
        //遍历其他元素
        for(int x = 1 ; x < arr.length ; x ++){
            if(arr[x] > max){
                max = arr[x] ;
            }
        }
        return max ;
    }

    /***
     * 这个功能是针对数组查询数组中某个元素的索引值
     * @param arr  在指定的数组中查询
     * @param key  要查找的指定元素
     * @return    返回结果就是的索引值,如果找不到,则返回-1
     */
    public static int getIndex(int[] arr,int key){
        //假设法
        int index = -1 ;
        for(int x = 0 ; x < arr.length ; x ++){
            if(key == arr[x]) {
                index = x ;
                break ;
            }
        }
        return index ;
    }

    /***
     * 这个功能是针对数据进行冒泡排序,最终数组是一个有序的
     * @param arr 针对指定的数组进行排序
     */
    public static void bubbleSort(int[] arr){
        for(int x = 0 ; x < arr.length-1; x ++){
            for(int y = 0 ; y < arr.length-1 -x ; y ++){
                //判断
                if(arr[y] > arr[y+1]){
                    int temp = arr[y] ;
                    arr[y] = arr[y+1] ;
                    arr[y+1] = temp ;
                }
            }
        }
    }
}

打开dos窗口 javadoc -d 文件夹名称 -author -version java文件(xxx.java --ArrayTool.java)

​ javaoc -d mydoc -author -version ArrayTool.java

6.面试题:this和super的区别

this和super 的区别

  • this:代表的当前类对象的地址值引用

  • super:代表的父类对象的地址值引用(代表父类的空间标识)

    访问成员变量
  • this.变量名; 访问的本类中的成员变量

  • super.变量名; 访问的是父类的成员变量

    访问构造方法:
  • this() ; 访问本类的无参构造方法

  • super() ;访问的父类的无参构造方法

  • this(xxx);访问的本类的有参构造方法

  • super(xxx);访问的父类的有参构造方法

    访问成员方法:
  • this.方法名();访问的是本类的成员方法

  • super.方法名() ;访问的是父类的成员方法

7.继承中加入静态代码块

继承的初始化:分层初始化,先让父类先初始化

代码块的优先级:*静态代码块随着类的加载而执行,但类只加载一次,所以静态代码块只执行一次

​ 优先级:静态代码块 > 构造代码块 > 构造方法


class Person{
    static{
        System.out.println("static Person{}");
    }
    public Person(){
        System.out.println("class Person(){}");
    }
    {
        System.out.println("Person{}");
    }
}
class Student extends  Person{
    {
        System.out.println("Student{}");
    }
    static{
        System.out.println("static Student{}");
    }
    public Student(){
        System.out.println("class Student(){}");
    }

    public Student(int i) {
        //super() ;
        System.out.println("class Student(int i){}");
    }
}
public class ExtendsTest2 {
    public static void main(String[] args) {
        Student s = new Student() ;
        System.out.println("--------------");
        Student s2 = new Student(10) ;
    }
}

8.final关键字

子类如果出现和父类一模一样的方法声明,则称为方法的重写(override)

方法的重载只和方法的名字,形参有关系,有返回值等无关。名字相同,形参不同。

如果父类不想让子类重写自己的某些方法时,父类的功能是独立的,子类只能使用。

java对于此类问题提供了专门的关键字:final 最终的,无法更改的。

final关键字的特点?

1)可以修饰类,该类不能被继承

2)可以修饰成员方法,该方法不能被重写

3)可以修饰变量,该变量是一个常量

面试题:final、finally和finalize()的区别

final的关键字描述以及的三个特点

finally:处理异常用到 try…catch…finally(后面讲)

finalize():跟垃圾回收器有关系:回收内存中没有更多引用的对象(后面在讲常用类使用以下)

9.多态

概念:一个事物在不同时刻的不同形态。

继承是类的继承,多态是方法的多态。即多态是方法在子类中所实现不同于父类的功能。

多态的前提条件:

​ 1)必须存在继承关系(extends)

​ 2)必须存在方法重写

​ 3)必须有父类引用指向子类对象

多态成员的访问特点:

​ Fu fu = new Zi();

​ 1)针对成员变量:编译看左,运行看左。(使用父类的成员变量)

​ 2)针对成员方法:编译看左,运行看右。(子类重写了父类的方法,所以访问的是 子类的方法)

​ 3)如果成员方法是静态方法:静态成员方法算不上重写,直接用类名来访问。

​ 编译看左,运行看左。

​ 4)构造方法:存在继承关系的时候需要先初始化父类,再对子类进行初始化(分层 初始化)

多态的好处:

​ 1)提高了代码的复用性:由继承保证

​ 2)提高了代码的扩展性:由多态保证

多态的弊端:

​ 无法通过父类引用指向子类对象产生的对象去访问子类对象的特有方法,需要进行向下类型转换

	Fu fu = new Zi();	//向上类型转换(自动)
	Zi zi = (Zi)fu;		//向下类型转换(强制转换)
//有一个动物类
class Animal2{
    //吃和睡
    public void eat(){
        System.out.println("动物饿了,都需要吃饭...");
    }
    public void sleep(){
        System.out.println("动物困了,都需要休息...");
    }
}

//两个子类
class Cat2 extends  Animal2{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫趴着睡觉");
    }
}
class Dog2 extends  Animal2{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗侧着睡觉");
    }
}
//猪类
class Pig extends Animal2{
    @Override
    public void eat() {
        System.out.println("猪吃白菜");
    }

    @Override
    public void sleep() {
        System.out.println("猪滚着睡觉...");
    }
}

//定义一个动物类的工具类:AnimalTool
class AnimalTool{

    //构造方法私有:不让外界new
    private AnimalTool(){}
   /* public static void createDog(Dog2 d){//如果方法的形式参数是类,----调用该方法传递的实际参数:需要当前类的具体对象
        d.eat();
        d.sleep();
    }
    //定义创建猫的方法
    public static void createCat(Cat2 c){
        c.eat();
        c.sleep();
    }*/

   //父类引用可以指向子类对象:形式参数就可以传递Animal2
    public static void createAnimal(Animal2 a){ //    Animal2 a =  new Dog2();
        a.eat(); //多态的成员方法访问问题
        a.sleep();
    }
}
多态中向下转型不当会出现ClassCastException异常(属于运行时期异常)

要使用向下转型,前提必须有父类引用指向子类对象 Fu f = new Zi() ;

遵循向下转型的格式: Zi z = (Zi)f; 必须心里清楚堆内存存储的类型

当前堆内存中的实例不是该类型时,就会出现问题!

//定义一个动物类
class Animal{
    public void eat(){
        System.out.println("动物都需要吃饭");
    }
}
//狗类
class Dog extends  Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
//猫类
class Cat extends  Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

//测试类
public class DuoTaiDemo {
    public static void main(String[] args) {
        //多态版测试猫
        Animal a = new Cat()  ;//此时 堆内存是猫       (猫是动物)

        Cat c = (Cat) a ;  //还原成猫类型  :猫是猫

        a = new Dog() ; //此时:堆内存是狗   (狗是动物)

        Dog d = (Dog)a; //还原成狗的类型: 狗是狗

        Cat cc = (Cat)a ;//现在没有报错:语法正确的:符合强转类型语法格式
    }
}

10.方法重载和方法重写的区别

方法重载:override

在一个类中定义多个方法,这些方法的方法名相同,参数列表不同,与返回值无关

参数列表:

​ 1)参数类型不同

​ 2)参数个数不同

​ 3)参数类型先后顺序不同

目的:为了提高功能的扩展性:同一个方法可以根据传入参数的不同而实现不同的功能。

方法重写:override

在继承关系中,子类出现了和父类一模一样的方法,这个子类将父类的功能覆盖(重写)。

重写的目的:为了沿用父类的方法,并且还需要使用子类的功能(具体的子类才具备具体的动作…)

方法重写中,子类对父类重写时子类方法的访问权限不能小于父类的访问权限!

实际开发中:有的时候需要将api提供一些功能进行重写,完成我们自己的业务需求!

后期使用:Servlet(server applet:针对服务端程序开发 :前后端的交互) JavaEE核心技术之一

11.抽象类

概念:现实世界事物中,某个事物是比较概括性(人/水果/动物),描述为抽象事物。

在程序中:将某个事物中的一些功能仅仅给出声明即可,没有方法体----->抽象方法---->此时这个类必须为抽象类!

关键字:abstract

抽象方法的格式:权限修饰符(一般情况都是public) abstract 返回值类型 方法名(形式参数列表) ;

抽象类的格式:abstra class 类名{}

抽象类的特点:

​ 1)有抽象方法的类一定是抽象类

​ 2)抽象类中不一定只有抽象方法 ,还可以非抽象方法(有方法体)

​ 3)抽象类不能实例化---->意思:不能创建对象

​ 如何实例化呢:通过具体的子类进行实例化(进行对象的创建), 抽象类多态 Fu fu = new Zi() ;Fu 类型 抽象类型

​ 4)抽象类的子类有两种情况:

​ 1)目前来说:如果抽象类的子类都是抽象类—毫无意义 因为子类也不能new ,除非再有具体 的子类

​ 2)抽象类的子类具体类—才能new :抽象多态的形式 Fu fu = new Zi() ;

抽象类的核心宗旨:就是强制子类必须完成的事情(要将父类中的所有的抽象方法必须重写,否则报错!)
抽象类成员的特点:

​ 1)成员变量:既可以定义变量,也可以常量:被final修饰

​ 2)成员方法:既可以定义为抽象方法,也可以定义为非抽象方法

​ 如果定义为抽象方法:关键字abstract(显示给出)

​ 3)构造方法: 存在无参构造/有参构造方法---->目的:分层初始化

//子类
//目前来说:如果抽象类的子类都是抽象类---毫无意义  因为子类也不能new ,除非再有具体的子类
//abstract class Cat extends Animal{

//具体类
 class Cat extends Animal{

    public Cat(){
        System.out.println("Cat的无参构造方法");
    }
    @Override
    public void eat() {
        System.out.println("猫吃鱼...");
    }

    @Override
    public void slepp() {
        System.out.println("猫趴着睡觉...");
    }

    //特有功能
    public void playGame(){
        System.out.println("猫玩毛线");
    }
}

class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void slepp() {
        System.out.println("狗侧着睡觉...");
    }

    //特有功能
    public void catchRabit(){
        System.out.println("狗可以抓兔子");
    }
}

//测试类
public class AbstractDemo {
    public static void main(String[] args) {

        //创建动物类对象
        //类名 对象名 = new 类名() ;
       // Animal a = new Animal()  ;//不能创建对象,如何实例化呢?

        //使用多态的形式: 当前的Animal类的子类一定是具体类
        Animal a = new Cat() ;//父类引用指向子类对象(父类---抽象类) : 抽象类多态
        a.eat();
        a.slepp();
       // a.playGame() ; 父类没有这个功能

        //向下转型
        Cat c = (Cat)a ;
        c.playGame();
        System.out.println("-------------------------");

        a = new Dog() ;
        a.eat();
        a.slepp();

        Dog d = (Dog) a;
        d.catchRabit();
    }
}

12.ClassCastException(类转换异常)、ArrayIndexOutOfBoundsException(数组角标越界异常)、NullPointerException(空指针异常)

NullPointerException:空指针异常,一般发生在引用类型new对象的时候,可能在经过一系列操作的时候 只定义了而没有具体的地址值,则会出现这种错误,给引用类型变量赋地址值即 可。解决方案:针对某个对象进行非空判断

ArrayIndexOutOfBoundsException:地址索引越界异常,一般是数组当中在访问时访问了超过下标的 地方,或者在字符串中,访问了超过下标的地方,解决就是在使用 过程中,下标值不能超出数组.length-1。

StringIndexOutOfBoundsException:字符串角标越界异常—>extends IndexOutOfBoundsException:角 标越界异常

​ “hello”---->底层---->‘h’,‘e’,‘l’,‘l’,‘o’

ClassCastException:类转换异常,一般发生于多态当中的向下转型,因为向下转型是强转,此时,我们 得清楚要转变量当中存的具体是和类的对象。如果发生此类错误,则重新思考当前 变量地址类型即可。故一定要知道fu的引用—堆内存的对象是谁。

13.abstract和哪些关键字冲突

1.static static修饰之后可以通过类名直接访问,然而抽象方法没有方法体,所以无意义

2.final final修饰之后的类不能被继承,所以冲突

3.private private修饰之后只能在本内中访问,所以冲突

14.成员变量和静态变量的区别

成员变量需要new初对象之外才可以进行访问,它存储在堆内存中;静态变量不属于任何对象,它隶属于类,通过类名访问,存储在静态方法区。

14.什么是接口,接口的特点,接口的成员特点

概念:它的本质就是体现一个现实世界事物所具有的的额外的扩展功能!

定义格式: interface 接口名{} ------>接口名遵循"标识符规则"---->大驼峰命名法

接口中的成员特点:成员变量只能是常量

​ 成员方法只能是抽象方法,不能有方法体,隐藏public abstract关键字。

​ 接口没有构造方法

接口的特点:1)不能实例化(不能创建对象)

​ 2)如何实例化

​ 接口实例化: 通过接口的子实现类(一定是具体类)进行实例化----接口多态(使用时最多的!)

​ 子实现类和接口的关系: implements 实现关系

//定义一个接口:
interface  Jump{ //跳高接口

   /* public void jump(){
        System.out.println("可以跳高了...");
    }*/
   public abstract  void jump() ;
}

//定义一个跳高猫类
class JumpCat implements Jump{ //实现关系--->关键字:implements

    @Override
    public void jump() {
        System.out.println("猫可以跳高了...");
    }
}

//测试类
public class InterfaceDemo {
    public static void main(String[] args) {
        Jump jump = new JumpCat() ;
        jump.jump(); //编译看左,运行看右!(接口只能有抽象方法)

    }
}
具体类、抽象类和接口之间的关系

​ 类与类之间的关系: extends 继承关系。只支持单继承,不支持多继承,但是可以多层继承

​ 类和接口的关系: implements关系:实现关系。一个类继承另一个类的同时,可以实现多个接口,中间 逗号给隔开

​ 接口与接口之间: extends:继承关系。不仅支持单继承,也可以多继承,中间使用逗号隔开

15.抽象类和接口的区别

1)成员的区别:
抽象类中:成员变量:既可以是常量也可以是变量
成员方法:既可以是抽象方法(abstract不能省略),也可以是非抽象方法
构造方法:既存在无参构造也存在有参构造(为了给当前类进行数据初始化)

1)成员的区别:
			抽象类中:成员变量:既可以是常量也可以是变量
					成员方法:既可以是抽象方法(abstract不能省略),也可以是非抽象方法
					构造方法:既存在无参构造也存在有参构造(为了给当前类进行数据初始化)
								  		 
			接口中:成员变量:只能是常量,存在默认的修饰符 public static final(可以省略不写)
				   成员方法:只能是抽象方法,存在默认修饰符  public abstract(可以省略不写)
				   构造方法:没有构造方法,接口中的所有方法都没有方法体

2)关系的区别(三点):
			类与类的关系: extends 继承关系。只支持单继承,不支持多继承,但是可以多层继承。
			类和接口的关系:  implements关系:实现关系。一个类继承另一个类的同时,可以实现多个接							口,中间逗号给隔开。
			接口与接口之间:  extends:继承关系。不仅支持单继承,也可以多继承,中间使用逗号隔开
	
3)设计理解区别:
			抽象类--->不能实例化---通过具体的子类实例化---->存在继承关系,体现的是一种 "is 				a"的关系。
	
			接口---->不能实例化--->通过具体的子实现类实例化---->谁如果实现了接口,就具备额外的功			 能,体现的是一种"like a"的关系。

16.选择排序

思想: 使用0角标对应的元素依次和后面角标对应的元素进行比较,小的往前放,第一次比较完毕。

​ 最小值出现在最小索引处,依次这样比较。

​ 比较的次数:数组长度-1次

代码实现
public class SeclectSort {

    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]+", ");
            }
        }
    }

    public static void selectSort(int[] arr){
        for (int i = 0; i < arr.length-1 ; i++) {
            for (int j = i+1;j < arr.length ; j++){
                if (arr[i] > arr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
            //printArray(arr);
        }
    }

    public static void main(String[] args) {
        int[] arr = {15,96,65,85,17,13};
        System.out.println("排序前:");
        printArray(arr);
        selectSort(arr);
        System.out.println("排序后:");
        printArray(arr);
    }
}

17.Java的权限修饰符

  • 默认修饰符
  • 私有修饰符:private
  • 受保护的 :protected
  • 公共的,公开的:public

作用范围:public > protected > 默认修饰符 > private

同一个包下的当前类同一个包下的子类/无关类不同包下子类不同包下的无关类
private
默认修饰符(default)
protected
public

18.内部类

概念:在一个类中定义另外一个类。如:在类A 中定义了类B,将类B就称为类A的内部类,类A就是外部类!

我们所说的类即为成员内部类:在一个类的成员位置中定义了另一个类。

特点:

​ 1.内部类可以访问外部类的成员,包括私有!

//外部类
class Outer{
    //成员变量
    public int num = 100 ;
    private int num2 = 200 ;

    class Inner{ //成员内部类
        //成员内部类的一个成员方法
        public void method(){
            System.out.println("method Inner");
            System.out.println();
            System.out.println(num2);
        }
    }

    //外部类的成员方法
    public void show(){
        //访问的成员内部类的method--->通过创建内部类对象来访问
        //method() ;错误的----访问的本类的method方法
        Inner inner = new Inner() ;
        inner.method();
   }
}

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

​ 2.外部类可通过格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象 直接访问内部类的成 员方法

class Outer2{
    private int num = 20 ;

    //成员内部类
    class Inner2{
        public void show(){
            System.out.println(num);
        }
    }

    //外部类的成员方法
    public void method(){
        // 创建内部类对象访问内部类的成员方法
    }
}

//测试类
public class InnerClassDemo2 {
    public static void main(String[] args) {

        //外部类名.内部类名  对象名 =  外部类对象.内部类对象;
        //适用于:通过外部类直接访问成员内部类的成员(前提条件:当前成员内部类是一个非静态类)
        Outer2.Inner2 oi = new Outer2().new Inner2() ;
        oi.show() ;
    }
}

​ 3.如果当前成员内部类是静态的, 里面的方法无论是静态的还是非静态的,都只能访问外部类的静态 成员,包括私有!

​ 如何直接访问静态成员内部类的成员呢?

​ 将静态的成员内部类看成是外部类的静态成员访问

​ 直接访问方式:外部类名.内部类名 对象名 = new 外部类名.内部类名() ;

class Outer3{
    //定义非静态的成员变量
    public int num = 50 ;
    private static int num2 = 20 ;

    //定义成员内部类:静态的           ---->静态的成员内部类可以看成是外部类的静态成员
    static class Inner3{//此时类都是静态
        public void show(){
           // System.out.println(num);
            System.out.println(num2);
        }
        public static void show2(){
           // System.out.println(num);
            System.out.println(num2);
        }
    }
}


//测试类
public class InnerClassDemo3 {
    public static void main(String[] args) {


        // 外部类名.内部类名 对象名  = 外部类对象.内部类对象;
        //Outer3.Inner3 oi = new Outer3().new Inner3() ;  适用不了了

        //   外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
        Outer3.Inner3 oi = new Outer3.Inner3() ;
        oi.show();
        oi.show2() ; //静态---不推荐对象名访问

        System.out.println("------------------------------");
        //show2()的另一种方式
        Outer3.Inner3.show2(); //show2()静态方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值