面向对象(下)

面向对象(下)

关键字 :static

/*
* static关键字的使用
* 1.static:静态的
* 2.static 可以用来修饰:属性、方法、代码块、内部类  不可以修饰构造器
* 3.使用static修饰属性:静态变量(类变量)
*       3.1 属性:按是否使用static修饰,又分为:静态属性vs非静态属性(实例变量)
*           实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象的
*               非静态属性时,是不会导致其他对象中同样的属性修改
*           静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,
*           会导致其他对象调用次静态变量时时修改过的.
*       3.2static修饰属性的其他说明:
*           ①静态变量随着类的加载而加载  可以通过类.静态变量的方式进行调用(类的加载要优先于对象的创建)
*           ②静态变量的加载要早于对象的创建.
*           ③由于类只会加载一次,则静态变量在内存中只会存在一份,存在方法区的静态域中
*
*           ④       类变量     实例变量
*           类       yes         no
*           对象     yes        yes
*
*       3.3 今天属性举例: System.out; Math.Pi;
*
* 4.使用static修饰方法,静态方法   (可以被重载,不可以重写)
*       ①随着类的加载而加载,可以通过类.静态方法的方式进行调用
*       ②      静态方法        非静态方法
*       类       yes             no
*       对象      yes             yes
*       ③静态方法中,只能调用静态的方法或属性
*        非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
*
* 5.static注意点:
*   5.1在静态方法内,不能使用this关键字,super关键字
*   5.2关于静态属性和静态方法的使用,大家都从生命周期的角度去理解
*
* 6.开发中,如何确定一个属性是否要生命为static的?
*     >属性是可以被多个对象所共享的,不会随着对象的不同而不同的
*	  >类中常量也常常声明为static
*   开发中,如何确定一个方法是否都要声明为static的?
*      >操作静态属性的方法,通常设置为static的
*      >工具类中的方法,习惯上声明为static的,比如(工具类)Math 、Arrays、Collexctions
* 补充:变量分为属性和局部变量*/

在这里插入图片描述在这里插入图片描述

public class staticTest {
    public static void main(String[] args) {
        Chinese c1 = new Chinese();
        c1.name="姚明";
        c1.age=35;



        Chinese c2 = new Chinese();
        c2.name="马龙";
        c2.age=30;
        c2.nation="100";

        System.out.println(c1.nation);
        c1.eat();
        Chinese.show();
        c1.show();
    }
}
//中国人
class Chinese{
    String name;
    int age;
    static String nation;
    public static void setNation(String nation) {
        Chinese.nation = nation;
    }
    public void eat(){
        System.out.println("中国人吃中餐");
    }
    public static void show(){
        System.out.println("我是一个静态方法");
        //不能调用非静态的结构
//        eat();
        //可以调用静态的结构
        System.out.println(nation);
    }
}

单例(Singleton)设计模式

所谓类的单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例.并且该类只提供一个取得其对象实例的方法.如果我们要让类在虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象,因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的.

饿汉式

//饿汉式
public class SingletonTest1 {
    public static void main(String[] args) {
        Bank bank1 = Bank.getInstance();
        Bank bank2 = Bank.getInstance();
        System.out.println(bank1==bank2); //true;
    }
}

class Bank{
    //1.私有化类的构造器
    private Bank(){

    }
    //2.内部创建类的对象
    //要去此对象也必须声明为静态的
    private static Bank instance =new Bank();
    //3.提供公共的方法,返回类的对象
    public static Bank getInstance(){
        return instance;
    }

}

懒汉式

/*
* 单例模式懒汉式
* */
public class SingletonTest2 {
    public static void main(String[] args) {
        Order order1= Order.getInstance();
        Order order2 = Order.getInstance();
        System.out.println(order1==order2);  //true;
    }
}
class Order{
    //1.私有化类的构造器
    private Order(){

    }
    //2.声明当前类对象,没有初始化
    //此对象也必须声明为static
    private static Order instance =null;
    //3.声明public、static的返回当前类对象的方法
    public static Order getInstance(){
        if(instance==null){
            instance=new Order();
        }
        return instance;
    }
}

两者对比

饿汉式:

1. 坏处:对象加载时间过长.
2. 好处:饿汉式是线程安全的

懒汉式:

​ 1.好处:延迟对象的创建.

​ 2.目前的写法坏处,线程不安全.—>到多线程内容时,再修改(目测应该是加锁)

单例设计模式优点

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接生成一个单例对象,然后永久驻留内存的方式类解决.

  • 举例:java.lang.Runtime;
private static Runtime currentRuntime = new Runtime();
private Runtime() {}
public static Runtime getRuntime() {
    return currentRuntime;
}
  • 应用场景,这里说的连接池数量是一个,是单例的,不需要造多个.

在这里插入图片描述

main方法的语法

/*
* main()方法的使用说明:
* 1.man()方法作为程序的入口
* 2.main()方法也是一个普通的静态方法
* 3.main()方法可以作为我们与控制台交互的方式.(之前,使用Scanner)*/
public class MainTest {
    public static void main(String[] args) {
        System.out.println("我是MainTest下面的Main");
        System.out.println(args.length);
        for (int i = 0; i < args.length; i++) {
            args[i] = "args_" + i;
            System.out.println(args[i]);
        }
    }
}
class Main{
    public static void main(String[] args) {
        MainTest.main(new String[10]);

    }
}

运行第一个main方法结果

我是MainTest下面的Main
0

运行第二个的

我是MainTest下面的Main
10
args_0
args_1
args_2
args_3
args_4
args_5
args_6
args_7
args_8
args_9

Process finished with exit code 0

  • 总结:

你点击右键运行时候是java虚拟就去用类.方法去调我们这个main方法,所以这个方法的权限要大些,声明为public

  • 自定义main里面的形参 点击红圈内的东西

在这里插入图片描述

  • 在下面红框内填入自己想要传的参数
    在这里插入图片描述

代码块

类的成员:属性 方法 构造器 代码块 内部类

/*
* 类的成员之四:代码块(或初始化快)
* 1.代码块的作用 用来初始化类、对象
* 2.代码块如果有修饰的话,只能使用static
* 3.分类:静态代码块vs 非静态代码块
*       >内部可以有输出语句
*       >随着类的加载而执行
* 4.静态代码块(可以定义多个)
*   >内部可以有输出语句
*   >随着类的加载而执行,而且只执行一次
*   >作用,初始化类的信息
*   >如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行.
*   >静态代码快的执行优先于非静态代码块
*	>靜态代码块内只能调用静态的属性、静态的方法、不能调用非静态的
* 5.非静态代码块 (可以定义多个)
*       >内部可以有输出语句
*       >随着对象创建而执行
*       >每创建一个对象,就执行一次非静态代码块
*       >作用:可以在创建对象时,对对象的属性进行初始化
*       >如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行.
*		>静态非静态方法,属性都可以调用
* */
  • 对属性可以赋值的位置(顺序也是这样的)
    1. 默认初始化
    2. 显示初始化 代码块中赋值(看写的顺序)
    3. 构造器中初始化
    4. 有了对象以后,可以通过对象.属性 或对象.方法进行赋值

练习题1

package duotai;

class Root{
    static {
        System.out.println("Root的静态初始化快");
    }
    {
        System.out.println("Root的普通初始化快");
    }

    public Root() {
        System.out.println("Root的无参数的构造器");
    }
}
class Mid extends Root{
    static {
        System.out.println("Mid静态代码块");
    }
    {
        System.out.println("MId的普通初始代块");
    }

    public Mid() {
        System.out.println("Mid的无参数的构造器");
    }

    public Mid(String msg) {
        //通过this调用同一类中重载的构造器
        this();
        System.out.println("Mid的带参数的构造器,其参数值:"+msg);
        System.out.println("Mid的无参构造器");
    }

}
class Leaf extends Mid{
    static int age;
    static {
        System.out.println("Left的静态初始化快");
    }
    {
        System.out.println("Left的普通初始化快");
    }

    public Leaf() {
        //通过super调用父类中带有一个字符串参数逇构造器
        super("郭京伟");
        System.out.println("Left的构造器");
    }
}
public class LeafTest {
    public static void main(String[] args) {
//        System.out.println(Leaf.age);
        new Leaf();
    }

}

结果:
Root的静态初始化快
Mid静态代码块
Left的静态初始化快
Root的普通初始化快
Root的无参数的构造器
MId的普通初始代块
Mid的无参数的构造器
Mid的带参数的构造器,其参数值:郭京伟
Mid的无参构造器
Left的普通初始化快
Left的构造器

总结:由父及子,静态先行.

练习题2

package duotai;
class Father{
    static {
        System.out.println("111父亲的静态代码块");
    }
    {
        System.out.println("222父亲的非静态代码块");
    }

    public Father() {
        System.out.println("333父亲的无参构造");
    }
}
public class Son extends Father{
    static {
        System.out.println("444Son中静态代码块");
    }
    {
        System.out.println("555Son中非静态代码块");
    }

    public Son() {
        System.out.println("666Son中的无参构造");
    }
	//虽然作为方法的入口,但是也是个静态方法,通过类去调,类去调之前要先
	//加载
    public static void main(String[] args) {
        System.out.println("777Son中静态main方法");
        System.out.println("******************");
        new Son();
        System.out.println("------------------");
        new Son();
        System.out.println("++++++++++++++++++");
        new Father();
    }
}
  • 结果:
111父亲的静态代码块
444Son中静态代码块
777Son中静态main方法
******************
222父亲的非静态代码块
333父亲的无参构造
555Son中非静态代码块
666Son中的无参构造
------------------
222父亲的非静态代码块
333父亲的无参构造
555Son中非静态代码块
666Son中的无参构造
++++++++++++++++++
222父亲的非静态代码块
333父亲的无参构造

练习题3

public class OrderTest {
    public static void main(String[] args) {
        Order order = new Order();
        System.out.println(order.orderId);
    }
}
class Order{
    {
        orderId=4;
//        System.out.println(orderId);  // 非法前向引用
        System.out.println("执行到这");
    }
    int orderId=3;


}

结果: 这两个执行顺序是看是谁在前就先执行谁,谁在后就后执行谁. 但是不能非法向前引用

执行到这
3

final关键字

/*
* final:最终的
*
* 1.final可以用来修饰的结构:类、方法、变量
*
* 2.final用来修饰一个类:此类不能被其他类所继承
*       比如说:String类、System类、StringBuffer类
*
* 3.final 用来修饰方法,表明此方法不可以被重写
*           比如Object类中getClass();
* 4.final 用来修饰变量:此时的"变量"就称为一个常量
*   4.1 final修饰属性:可以考虑赋值的位置有显式初始化 代码块赋值  构造器中初始化
*       如果你赋的值可能出异常,那么放到代码块上赋值
*   4.2 final修饰局部变量:
*       尤其是使用final修饰形参时,表名此形参是一个常量.当我们调用此方法时,
*       给常量形参赋一个实参,一旦赋值,就只能在方法体内使用此形参,但不能进行重新赋值.
*  static final:用来修饰 属性 方法
*       用来修饰属性,全局常量
*       用来修饰方法:
* */
public class FinalTest {
    final int WIDTH=10;
    final int LEFT;
    final int RIGHT;

    {
        LEFT=1;
    }

    public FinalTest() {
        RIGHT = 2;
    }
    public FinalTest(int n) {
        this();
    }

    public void doWidth(){

    }
    public void show(){
        final int NUM=10;  //此时表示常量
    }
    public void show(final int num){
	//  num=20;//编译不通过
        System.out.println(num);
    }

    public static void main(String[] args) {
        FinalTest finalTest = new FinalTest();
        finalTest.show(3);
    }
}
final class FinalA{

}
//class B extends FinalA{}  报错,FinalA不能被继承

抽象类与抽象方法

abstract关键字的使用

  1. abstract:抽象的

  2. abstract可以用来修饰的结构:类、方法

  3. abstract修饰类:抽象类

    此类不能实例化

抽象类中一定有构造器,便于子类实例化调用(涉及、子类对象实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象实例化

  1. abstract修饰方法、抽象方法

抽象方法只有方法的声明、没有方法体

包含抽象方法的类,一定是一个抽象类,反之,抽象类中是可以没有方法体的

若子类重写了父类中所有的抽象方法后,此类才可以被实例化

若子类没有重写了父类中所有的抽象方法,此类是一个抽象类、需要使用abstract修饰

  • abstract注意点
    • abstract不能用来修饰:属性、构造器等结构
    • abstract不能用来修饰私有方法、静态方法、final的类
public class AbstractTest {
    public static void main(String[] args) {
        //一旦Person类抽象了,就不可以实例化
//        Person p1 = new Person();
//        p1.eat();

    }
}
abstract class Person{
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //不是抽象方法
//    public abstract void eat1(){
//    }
    //抽象方法
    public abstract void eat();
    public void walk(){
        System.out.println("人走路");
    }
}
class Student extends Person{
    public Student(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("学生多吃好吃的");
    }


}

抽象类的匿名子类

public class PersonTest {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method(dog);  //非匿名类的非匿名对象
        method(new Dog()); //非匿名的类的匿名的对象
        //创建了一个匿名子类对象:
        Animal animal=new Animal() {

            @Override
            public void eat() {
                System.out.println("匿名子类eat");
            }
        };
        method(animal);

    }

    public static void method(Animal animal){
        animal.eat();
    }
}
abstract class Animal{
    public abstract void eat();

}
class Dog extends Animal{

    @Override
    public void eat() {

    }
}
运行结果:
匿名子类eat

创建匿名子类的匿名对象

method(new Animal() {
    @Override
    public void eat() {
        System.out.println("匿名子类的匿名对象");
    }
});

模板方法设计模式

  • 抽象类的应用:模板的设计模式
public class TemplateTest {
    public static void main(String[] args) {
        Template t=new SubTemplate();
        t.spendTime();
    }
}
abstract class Template{
    //用来计算纽段代码执行所需要花费的时间
    public void spendTime(){
        long start=System.currentTimeMillis();
        code();  //不确定的部分,易变的部分
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:"+(end-start));
    }
    public abstract void code();
}
class SubTemplate extends Template{
    @Override
    public void code() {
        for (int i = 2; i < 20; i++) {
            boolean flag=false;
            for (int j = 2; j <=Math.sqrt(i); j++) {

                if(i%j==0.0){
                    flag=true;
                    break;
                }

            }
            if(!flag){
                System.out.println("素数"+i);
            }
        }
    }
}
结果:
素数2
素数3
素数5
素数7
素数11
素数13
素数17
素数19
花费的时间为:0

Process finished with exit code 0

接口

概述:

​ 一方面,有时必须从几个类中派生出一个子类,继承他们所有的属性和方法,但是,Java不支持多重继承.有了接口,就可以得到多重继承的效果了.

​ 另一方面,有时必须必须从几个类中抽取出一些共同的行为特征,而他们之间有没is-a(子类 is a父类)的关系,仅仅是具有相同行为特征而已,例如:鼠标、键盘、扫描仪、摄像头、充电器等都支持USB接口.

​ 接口就是规范,定义的是一组规则,体现了现实世界中"如果你是/要…则必须能…"思想.继承时一个"是不是"的关系,而接口实现则是"能不能"的关系.

​ 接口的本质是契约,标准,规范,就像我们法律一样,制定好后大家都要遵守.


在这里插入图片描述在这里插入图片描述

接口的使用

  1. 接口使用interface来定义

  2. Java中,接口和类是并列的两个结构

  3. 如何定义接口:定义接口中的成员

    1. JDK7及以前:只能定义全局常量和抽象方法

      全局常量:public static final的 (但是书写时候可以不写,但是默认还在)

      抽象方法:public abstract的

    2. JDK8:除了定义全局常量和抽象方法之外、还可以定义静态方法、默认方法(略)

  4. 接口中是不能定义构造器!意味着接口不可以被实例化

  5. Java开发中,接口通过让类去实现(implements)的方式来使用

    • 如果实现类实现了接口中所以的抽象方法,则此实现类皆可以实例化
    • 如果实现类没有实现接口中的所有抽象方法,则此实现类仍为一个抽象类
  6. Java类可以实现多个接口—>弥补了单继承的局限性

    格式:class AA extends BB implement CC,DD,EE

  7. 接口和接口之间可以继承,而且可以多继承

interface AA{
    void mehtod1();
}
interface BB{
    void mehtod2();
}
interface CC extends BB,AA{

}
  1. 接口的具体使用,体现多态性
  2. 接口,实际上可以看作是一种规范.

项目的具体需求是多变的,我们必须以不变应万变才能从容开发,此处的不变就是规范.因此,我们开发项目往往都是面向接口编程.

package shangguigu.day8;
/*
* 接口的使用
* 1.接口的使用上也满足多态性
* 2.接口实际上就是一种规范
* 3.开发中,体会面向接口编程*/
public class USBTest {
    public static void main(String[] args) {
        Computer computer = new Computer();
        //1.创建了接口的非匿名实现类的的非匿名对象
        Flash flash = new Flash();
        computer.transferData(flash);
        //2.创建了接口的非匿名实现类的匿名对象
        computer.transferData(new Flash());
        //3.创建接口的匿名实现类的非匿名对象
        USB phone=new USB() {
            @Override
            public void start() {
                System.out.println("手机333");
            }

            @Override
            public void stop() {
                System.out.println("手机333");
            }
        };
        computer.transferData(phone);

        //4.创建了接口的匿名实现类的匿名对象
        computer.transferData(new USB() {
            @Override
            public void start() {
                System.out.println("mp3开始工作");
            }

            @Override
            public void stop() {
                System.out.println("mp3结束工作");
            }
        });

    }
}
interface USB{
    //常量:定义了长、宽、最大最小的传输速度等
    void start();
    void stop();
}
class Computer{
    public void transferData(USB usb){
        usb.start();
        System.out.println("具体的传输数据细节");
        usb.stop();
    }
}
class Flash implements USB{

    @Override
    public void start() {
        System.out.println("U盘开启工作");
    }

    @Override
    public void stop() {
        System.out.println("U盘结束工作");
    }

}
class Printer implements USB{

    @Override
    public void start() {
        System.out.println("打印机开启工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机结束工作");
    }
}

面试题:抽象类与接口有哪些异同?

内容来自:

含有abstract修饰符的class即为抽象类,abstract 类不能创建实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

下面比较一下两者的语法区别:

1. 抽象类可以有构造方法,接口中不能有构造方法。

2. 抽象类中可以有普通成员变量,接口中没有普通成员变量

3. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

4. 抽象类中的抽象方法的访问类型可以是publicprotected和(默认类型,虽然

eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

5. 抽象类中可以包含静态方法,接口中不能包含静态方法

6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

7. 一个类可以实现多个接口,但只能继承一个抽象类。

**下面接着再说说两者在应用上的区别:**

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:
————————————————
版权声明:本文为CSDN博主「qq_41933748」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41933748/article/details/82670072

接口的应用:代理模式

在这里插入图片描述

//静态代理
package shangguigu.day8;
/*
* 接口的应用:代理模式
* */
public class NetWorkTest {
    public static void main(String[] args) {
        Server server = new Server();
//        server.browse();
        ProxyServer proxyServer = new ProxyServer(server);
        proxyServer.browse();
    }
}
interface NetWork{
    public void browse();

}
//被代理类
class Server implements NetWork{

    @Override
    public void browse() {
        System.out.println("真是的服务器访问网络");
    }
}

//代理类
class ProxyServer implements NetWork{
    private NetWork work;
    public ProxyServer(NetWork work){
        this.work=work;
    }
    public void check(){
        System.out.println("联网之前的检查工作");
    }
    @Override
    public void browse() {
        check();
        work.browse();

    }
}

举例:代理类就是经纪人,被代理类就是明星

接口的应用:工厂设计模式

工厂模式:实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的.

1.简单工厂模式

2.工厂方法模式

3.抽象工厂模式

面试题1

  • 答案是啥?写的有误么?
interface A{
    int x=0;
}
class B {
    int x = 1;
}
public class C extends B implements A{


    public void pX(){
    //   System.out.println(x);  //报错 不知道调的是谁的
        System.out.println(super.x); //1
        //没有super.super这个的调用方式
        //System.out.println(super.super.);
        System.out.println(A.x);  //0
    }

    public static void main(String[] args) {
        new C().pX();
    }
}
结果:
1
0

面试题2

在这里插入图片描述

  • ball中实现一个play()方法就行,不会报错,因为两个接口的方法都是play()相当于把两个接口的方法都实现了.
  • 报错的地方是ball=new Ball(“Football”);因为ball是继承自接口,默认修饰符是public static final是静态的不可以修改

JDK8后接口的新特性

package shangguigu.day8;

public class SubClassTest {
    public static void main(String[] args) {
        SubClass s = new SubClass();

        //s.method1()  不行
        //SubClass.method1() 不行
        CompareA.method1();  //知识点1:接口中定义的静态方法,只能通过接口来调用

        //知识点2:通过实现类的对象,可以调用接口中的默认方法
        //如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
        s.method2();
        //知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,
        //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法,子类有肯定是以子类的为准  类优先原则
        //知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
        //那么在实现类没有重写此方法的情况下,报错.--->接口冲突
        //这就需要我们必须在实现类中重写此方法
        s.method3();
    }
}
class SubClass extends SuperClass implements CompareA{
    public void method2(){
        System.out.println("Subclass:上海");
    }
    //知识点5:如何在子类的方法中调用父类、接口中被重写的方法
    public void myMethod(){
        method2();//自己定义的重写的方法
        super.method3();//调用的是父类中声明的
        CompareA.super.method2();  //调用接口中的方法2
        CompareA.super.method3();

    }

}
package shangguigu.day8;

public class SuperClass {
    public void method3(){
        System.out.println("Super的:上海");
    }
}
package shangguigu.day8;
/*
* JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法*/
public interface CompareA {
    //静态方法
    public static void method1(){
        System.out.println("Compare!:北京");
    }
    //默认方法
    public default void method2(){
        System.out.println("CompareA:上海");
    }
    default void method3(){
        System.out.println("CompareA:上海");
    }
}

内部类

  • 类的内部成员之5:内部类
  1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类

  2. 内部类的分类:成员内部类(静态、非静态)vs局部内部类(方法内、代码块内、构造器内)

public class InnerClassTest {
}
class Person1{
    //静态成员内部类
    static class Dog{}
    //非静态成员内部类
    class bird{}
    public void method(){
        //局部内部类
        class AA{}
    }
    {
        //局部内部类
        class BB{}
    }

    public Person1() {
        //局部内部类
        class CC{}
    }
}
  1. 成员内部类:

    • 一方面,作为外部类的成员

      • 调用外部类的成员
      • 可以用static修饰
      • 可以被4中不同的权限修饰.
    • 另一方面,作为一个类:

      • 类内可以定义属性和方法和构造器等
      • 可以用final修饰,表示此类不能被继承,言外之意,不使用可以被继承
      • 可以被abstract修饰,表明不能被实例化

4.关注如下3个问题

​ * 4.1 如何实例化成员内部类

​ * 4.2 如何在成员内部类中区分调用外部类的结构

​ * 4.3开发中局部内部类的使用

package shangguigu.day8;

public class InnerClassTest {
    public static void main(String[] args) {
        //创建Dog实例(静态成员内部类)
        Person1.Dog dog = new Person1.Dog();
        //创建Bird实例(非静态成员内部类):
//        Person1.bird bird=new Person1.Bird();//错误的
        Person1 p = new Person1();
        Person1.bird bird = p.new bird();
        bird.sing("过");
    }
}
class Person1{
    public void eat(){
        System.out.println("吃");
    }
    //静态成员内部类
    static class Dog{
        String name;

        public Dog() {

        }
        public void show(){
            System.out.println("我gou");

        }
    }
    //非静态成员内部类
    class bird{
        String name;

        public bird() {

        }
        public void sing(String name){
            System.out.println(name); //方法的形参
            System.out.println("我是一个小小鸟");
            eat();//省略了Person1.this.
            Person1.this.eat();  //调用外部类的属性

        }
    }
    public void method(){
        //局部内部类
        class AA{}
    }
    {
        //局部内部类
        class BB{}
    }

    public Person1() {
        //局部内部类
        class CC{}
    }
}
  • 局部内部类
package shangguigu.day8;

public class InnerClassTest {
    //开发中很少见
    public void method(){
        //局部内部类
        class AA{}
    }
    //返回一个实现了Comparable接口的类的对象
    public Comparable getComparable(){
        //创建一个实现了Comparable接口的类:局部内部类
        class MyComparable implements Comparable{

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
    }

}
员内部类
    static class Dog{
        String name;

        public Dog() {

        }
        public void show(){
            System.out.println("我gou");

        }
    }
    //非静态成员内部类
    class bird{
        String name;

        public bird() {

        }
        public void sing(String name){
            System.out.println(name); //方法的形参
            System.out.println("我是一个小小鸟");
            eat();//省略了Person1.this.
            Person1.this.eat();  //调用外部类的属性

        }
    }
    public void method(){
        //局部内部类
        class AA{}
    }
    {
        //局部内部类
        class BB{}
    }

    public Person1() {
        //局部内部类
        class CC{}
    }
}
  • 局部内部类
package shangguigu.day8;

public class InnerClassTest {
    //开发中很少见
    public void method(){
        //局部内部类
        class AA{}
    }
    //返回一个实现了Comparable接口的类的对象
    public Comparable getComparable(){
        //创建一个实现了Comparable接口的类:局部内部类
        class MyComparable implements Comparable{

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值