JavaSE基础——(10)面向对象之权限修饰符与匿名内部类

目录

一、java中的包

1.1package关键字的概述及作用

1.2包的定义及注意事项

1.3不同包下类之间的访问

二、java中常见修饰符

2.1修饰符

2.2类

2.3成员变量

2.4构造方法

2.5成员方法

三、内部类

3.1内部类概述

3.2内部类访问特点

3.3私有内部类和静态内部类

3.4成员内部类的面试题

3.5匿名内部类的定义与使用

3.6匿名内部类重写多个方法调用

3.7匿名内部类的面试题


一、java中的包

1.1package关键字的概述及作用

在java的学习过程中,我们会遇到各种各样的类,如果类的数量过多,我们很难去管理,

而包的作用,就是将字节码(.class)进行分类存放,包其实就是文件夹。

1.2包的定义及注意事项

包的定义用package关键字,格式为

package 包名
多级包用.分开 例:package core.alg.de

定义包的注意事项

  • package语句必须时陈旭的第一条可执行的代码
  • package语句在一个java文件中只能有一个
  • 如果没有package,则默认表示无包名

1.3不同包下类之间的访问

我们首先在工程下面新建一个数学工具类Mathtool,然后将这个class放入com/tz/文件路径下,

接着实现一个简单的整型数字相加的函数add,并将该类定义在包com.tz下

package com.tz;
public class Mathtool {
    public static int add(int a,int b){
        return a+b;
    }
}

接着我们在主类中使用import语句调用该包的add函数,

import com.tz.Mathtool;
public class Main{
    public static void main(String args[]){
        System.out.println(Mathtool.add(1,1));
    }
}

接着我们看输出结果:

 可以看到不同包下类之间的访问可以通过import语句进行实现。

我们在使用import的时候需要注意以下事项:

import com.tz.*

当我们使用”*“符号时,程序会在com/tz/路径下寻找所有匹配的包,使用该符号虽然很简便,但是如果在开发过程中包的类比较多,那么该方法就存在一个查找的效率问题,所以一般使用精确导入类名这种方法。

二、java中常见修饰符

2.1修饰符

  • 权限修饰符:private(默认),protected,public
  • 状态修饰符:static,final
  • 抽象修饰符:abstract

2.2类

  • 权限修饰符:默认修饰符,public(私有的类外部无法调用,所以一般不用private修饰)
  • 状态修饰符:final
  • 抽象修饰符:abstract

在类中使用较多的为public修饰符。

2.3成员变量

  • 权限修饰符:private(默认),protected,public
  • 状态修饰符:static,final

在成员变量中使用较多的为private修饰符。

2.4构造方法

  • 权限修饰符:private(默认),protected,public

在构造方法中使用最多的是public修饰符。

2.5成员方法

  • 权限修饰符:private(默认),protected,public
  • 状态修饰符:static,final
  • 抽象修饰符:abstract

在成员方法中使用最多的是public修饰符。

三、内部类

3.1内部类概述

内部类即在类中定义的类,而相对的在外面的类即为外部类。

3.2内部类访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员
  • 外部类要访问内部类的成员,必须要创建对象:
外部类名.内部类名 对象名=外部类对象.内部类对象

我们通过一段代码来体会内部类的使用方法:

public class InnerOuter {
    public static void main(String []args){
        OuterClass.InnerClass i=new OuterClass().new InnerClass();
        i.InnerPrint();
    }
}

class OuterClass{
    private String stirng="private string";
    class InnerClass{
        public void InnerPrint(){
            System.out.println(stirng);
        }
    }
}

看到输出结果如下:

3.3私有内部类和静态内部类

如果我们将内部类私有化,则在其他类中无法访问,则必须通过外部类的某个方法访问内部类对内部类进行某些操作

class OuterClass{
    private String stirng="private string";
    private class InnerClass{
        public void InnerPrint(){
            System.out.println(stirng);
        }
    }
    
    public void printInner(){
        InnerClass i=new InnerClass();
        i.InnerPrint();
    }
}

如果这个内部类是静态的,那么我们就可以通过以下操作访问静态内部类的非静态方法

OuterClass.InnerClass oi=new OuterClass.InnerClass();
oi.InnerPrint();

如果当问静态内部类的静态方法,则直接使用类名和方法名调用即可

OuterClass.InnerClass.staticPrint();

3.4成员内部类的面试题

public class InnerOuter {
    public static void main(String []args){
        OuterClass.InnerClass oi=new OuterClass().new InnerClass();
        oi.show();
    }
}
//使用已知的变量,在控制台输出30,20,10
class OuterClass{
    public int num=10;
    class InnerClass{
        public int num=20;
        public void show(){
            int num=30;
            System.out.println(?);
            System.out.println(?);
            System.out.println(?);
        }
    }
}

第一个比较简单,直接访问show函数中的num变量,填num就行,

第二个可以通过this指针访问内部类的num变量,填this.num,

第三个则通过外部类名加this指针访问num变量,填OuterClass.this.num。

通过这个面试题我们知道,内部类可以获取到外部类的成员,通过外部类名.this.成员名即可访问。

3.5匿名内部类的定义与使用

匿名内部类就是内部类的一种简化写法,即没有名字的内部类,

在使用匿名内部类时,需要存在一个类或者接口,这个类可以是具体类也可以是抽象类,

定义一个匿名内部类的格式如下:

new 类名or接口名(){
    重写方法;
};

我们通过一个例子来看看如何使用匿名内部类:

public class InnerOuter {
    public static void main(String []args){
        Outer o=new Outer();
        o.method();
    }
}

interface Inter{
    public void print();
}

class Outer{
    public void method() {
        new Inter() {
            public void print() {
                System.out.println("匿名内部类");
            }
        }.print();
    }
}

我们是在类的方法中,直接使用new关键字实现类或者接口中需要重写的某个方法,

并且在new语句之后调用重写的方法,运行结果如下:

3.6匿名内部类重写多个方法调用

当我们需要调用匿名内部类的多个方法时,可以通过父类引用指向子类对象来实现

public class InnerOuter {
    public static void main(String []args){
        Outer o=new Outer();
        o.method();
    }
}

interface Inter{
    public void print1();
    public void print2();
}

class Outer{
    public void method() {
        Inter i=new Inter() {
            public void print1() {
                System.out.println("匿名内部类1");
            }
            public void print2() {
                System.out.println("匿名内部类2");
            }
        };
        i.print1();
        i.print2();
    }
}

可以看到输出结果

但是我们在碰到要重写接口或者类的多个函数时,一般不用匿名内部类,直接使用内部类即可。

匿名内部类在开发中经常被当作参数传入,我们通过一个例子体会其作用:

public class InnerOuter {
    public static void main(String []args){
        Outer outer=new Outer();
        outer.method(new Inter(){
            public void print() {
                System.out.println("print");
            }
        });
    }
}
abstract class Inter{
    public void print(){};
}

class Outer{
    public void method(Inter i) {
        i.print();
    }
}

可以看到匿名内部类被当作了一个对象,传入了参数中,在开发中我们就可以节省一些时间,

不用再继承抽象类然后用父类引用指向子类对象,直接在参数中使用匿名内部类即可。

3.7匿名内部类的面试题

要求在指定位置补齐代码,在控制台中输出"HelloWorld"

public class InnerOuter {
    public static void main(String []args){
        Outer.method().print();
    }
}

interface Inter{
    void print();
}

class Outer{
    //请输入你的代码
}

主函数中我们可以看到method这个方法是通过类名直接调用,那么method就是静态方法,

然后接着调用print方法,则证明method这个方法返回值是一个对象,并且这个对象可以调用接口Inter的方法print,

那么返回值类型就是Inter对象,然后我们在return的时候,返回一个Inter对象就可以,

接下来我们使用匿名内部类来创建Inter对象并且实现print方法即可。

class Outer{
    //请输入你的代码
    public static Inter method(){
        return new Inter() {
            public void print() {
                System.out.println("HelloWorld");
            }
        };
    }
}

输出结果为

在这个面试题中,比较重要的是能发现调用方法之后还能继续调用方法,那么调用方法后返回值一定是对象。

猜你喜欢

转载自blog.csdn.net/weixin_39478524/article/details/112268560