Java基础-面向对象-封装继承多态

目录

面向对象

1.类

2.对象

3.属性

4.方法

5.封装

6.继承 extends

7.多态

8. abstract关键字(抽象类)

9. final关键字

10. interface关键字(接口)

11. static关键字

12. this() & super()

13.匿名内部类


面向对象

面向对象和面向过程是开发中两个编程思想

c语言是面向过程的

java,php,python这些是面向对象的

面向对象就是找合适的对象做合适的事情,得到你想要结果

面向过程就是亲力亲为,自力更生。

其本质是以建立模型体现出来的抽象思维过程和面向对象的方法(百度百科)
是一种编程思维,也是一种思考问题的方式
​
如何建立面向对象的思维呢?
1、先整体,再局部
2、先抽象,再具体
3、能做什么,再怎么做

1.类

类:是对一切相似事物的统称。是一个泛泛的概念。可以去描述这一类事物的特征(属性)和行为(方法)

2.对象

对象:是一个具体的,独立的,唯一的,特殊实体。

类和对象的关系:对象是属于类的,对象具备类的特征和行为

2.1类与对象的定义格式

类的定义:
class 类名称{
属性名称;
返回值类型 方法名称(){}
}
​
对象的定义:
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;
​
如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性:对象.属性 ;
调用类中的方法:对象.方法();
​
在java中对象声明有两种含义
声明对象:Horse horse= null; ; //表示声明了一个对象,但是此对象无法使用,horse没有具体的内存指向
实例化对象:horse= new Horse() ;// 表示实例化了对象,可以使用
​
horse.eat(); //通过对象调用方法
new Horse().eat();//匿名对象调用方法
​
​

2.2对象与内存分析

new 关键字表示创建一个对象
new 关键字表示实例化对象
new 关键字表示申请内存空间
注意:如果使用一个没有申请内存空间的对象,会报空指针异常:java.lang.NullPointerException

(1)new关键字:表示向内存申请空间,也表示实例化一个对象,创建一个对象。

(2)一个对象在内存中的大小,由该对象的所有属性所占的内存大小的总和。引用类型变量在32位系统上占4个字节,在64位系统上占8个字节。加上而外的对象隐性数据所占的大小。 (3)相同的类型才可以赋值

(4)不同的引用,指向同一个对象,任何一个引用改变对象的值,其它引用都会反映出来。 (5)编程时要注意的问题,在确定不使用对象时,要尽早释放对象:引用=null

(6)当一个堆中的对象没有被任何引用变量所指向时,该对象会被JVM 的 GC 程序认为是垃圾对象,从而被回收

3.属性

特征:就是一类事物的属性,比如人的年龄,身高,性别,体重.......不

会动的。 属性!!!!!

4.方法

4.1定义:

行为:吃饭睡觉,打豆豆,拖地,做饭,喂孩子,喝枸杞。会动的。 方法!!!!!

4.2成员方法

成员方法必须有返回类型 即使是没有返回,也要写上void

4.3构造方法

构造函数没有返回类型,而且和类名一样!

(1)构造方法名称与类名相同,没有返回值声明(包括 void)

(2)构造方法用于初始化数据(属性)

(3)每一个类中都会有一个默认的无参的构造方法

(4)如果类中有显示的构造方法,那么默认构造方法将无效

(5)如果有显示的构造方法,还想保留默认构造 方法,需要显示的写出来。

(6)构造方法可以有多个,但参数不一样,称为构造方法的重载

(7)在构造方法中调用另一个构造方法,使用this(...),该句代码必须在第一句。

(8)构造方法之间的调用,必须要有出口。

(9)给对象初始化数据可以使用构造方法或setter方法,通常情况下,两者都会保留。 (10)一个好的编程习惯是要保留默认的构造方法。(为了方便一些框架代码使用反射来创建对象)

(11)private Dog(){},构造方法私有化,当我们的需求是为了 保正该类只有一个对象时(单例模式就是私有化构造器)。

public class Test{
public Test(){} //构造函数
public Test(int i)(){} //构造函数
public void test(){}//
public int test2(){}//方法!
}
带参构造方法:
public Dog(String name){
this.name = name;
}
​
多参构造方法:
public Dog(String name,int age){
this.name = name;
this.age = age;
}

4.4静态方法

public static void tex(){}

5.封装

如果想要对类的属性进行封装的话:
要使用关键字private修饰
定义get和set方法
封装之前:属性都可以直接访问和修改
封装之后:属性是成员变量,私有化属性,可以更加规范对于成员变量的操作,使得其他对象不能直接访问属性

如果想要对类的属性进行封装的话:

1.使用关键字private (私有的) 修饰

2.定义get和set方法

注意事项:

1.类下面的所有的成员变量全部都要私有化(private)。这是一种规范。

2.可以更加规范对于成员变量的操作

3.可以隐藏一部分代码的操作过程

封装之前:属性都可以直接访问和修改
class Person{
  String name;
  int age;
}
​
封装之后:
class Person{
  //属性是成员变量,私有化属性,使得其他对象不能直接访问属性
  private String name;
  private int age;
  //参数及方法内定义的变量是局部变量
  public void setName(String name){
  this.name = name;}
  public String getName(){
  return name;}
}

6.继承 extends

【注意】

1.子类可以通过继承获得父类的非私有的化的成员属性和成员方法

2.子类不能使用父类的私有化的成员属性和成员方法

继承是面向对象三大特征之一
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类
​
被继承的类称为父类(超类),继承父类的类称为子类(派生类)
通过继承可以实现代码重用
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
构造器而言,它只能够被调用,而不能被继承,可以通过使用super()进行调用,
对于继承而已,子类会默认调用父类的构造器,但是如果没有默认的父类构造器,子类必须要显示的指定父类的构造器(通过super()),而且必须是在子类构造器中做的第一件事(第一行代码)。
对于protected而言,它指明就类用户而言,他是private,但是对于任何继承与此类的子类而言或者其他任何位于同一个包的类而言,他却是可以访问的
Java 的继承是单继承,但是可以多重继承,
​
​
继承是发生在多个类之间,JAVA只能单继承,允许多层继承。
对于继承的类而言,他是超类,或父类,他的私有属性和构造方法不能被继承,但是被protected修饰的属性或方法可以被子类继承,
对于子类而言,继承父类使用关键字extends,拥有自己的属性和方法,也拥有父类非 private 的属性、方法,也可以用自己的方式实现父类的方法,
实例化子类对象,会先调用父类的构造方法,如果父类中没有默认的构造方法,那么子类必须通过super()来调用父类的带参构造方法,super也只能在子类构造方法中的第一句,就protected而言,指明当前类是一个私有类,而继承当前类的子类,或者位于同一个包的其他类而言,他的属性和方法却是可以访问的

(1)继承是发生在多个类之间
(2)继承使用关键字extends
(3)JAVA只能单继承,允许多层继承
(4)被继承的类叫父类(超类),继承父类的类叫子类(派生类)
(5)在父类中的非私有属性和方法可以被子类继承
(6)protected(受保护的访问权限修饰符),修饰的属性或方法可以被子类继承
(7)构造方法不能被继承
(8)创建对象会调用构造方法,调用构造方法不一定就是创建对象
(9)实例化子类对象,会先调用父类的构造方法,如果父类中没有默认的构造方法,那么子类必须显示的通过super(...)来调用父类的带参构造方法,super也只能在子类构造方法中的第一句

继承的好处:
a、提高代码的复用性
b、提高代码的维护性
c、让类与类之间产生关系,是多态的前提
继承的缺点:增强了类与类之间的耦合性

6.1重写 Override

背景:

子类通过继承可使用父类的非私有化的成员方法,但是父类的方法有可能满足不了子类的需求了。

所有子类,在不修改父类的方法的情况下,对方法进行重写。

重写的规则:

1.参数列表、方法名、返回值必须完全一致

2.父类中的方法若使用private、static、final任意修饰符修饰,那么,不能被子类重写。

3.声明为final的方法不能被重写

4.声明为static的方法不存在重写

5.访问权限不能比父类更低

6.重写之后的方法不能抛出更宽泛的异常

6.2重载 Overload

方法的重载:Overload
1.要求在同一个类内
2.要求方法名字必须一致
3.要求形式参数必须不一致
方法的重写:Override
1.不在一个类内
2.必须是继承关系
3.方法名字返回值参数列表必须一致

方法的重载:

1.要求在同一个类内

2.要求方法名字必须一致

3.要求形式参数必须不一致

方法的重写:

1.不在一个类内

2.必须是继承关系

3.方法名字返回值参数列表必须一致

7.多态

定义:父类的引用指向子类的对象。或者接口的引用指向接口实现类的对象

使用的优点:
1.可替换性高,
2.可以让方法的范围更加灵活、范围更加广阔一点。
3.可扩展性强

java多态的条件:
1.继承
2.重写
3.父类的引用指向子类的对象

定义:

父类的引用指向子类的对象。或者接口的引用指向接口实现类的对象

使用的优点:

1.可替换性高,可以让方法的范围更加灵活、范围更加广阔一点。

3.可扩展性强

java多态的条件:

1.继承

2.重写

3.父类的引用指向子类的对象

Animal tiger = new Tiger();

|| ||

(父类) (子类的对象)

8. abstract关键字(抽象类)

背景:

父类的方法,子类可以继承使用。但是父类的方法不一定适用于子类。或者说父类不期望子类重写这个方法。

但是目前的语法中,如果子类不重写父类的方法,是可以的,是不报错的。

期望有一种语法,要求子类必须重写【强制重写】

【定义】

允许不同类的对象对同一消息做出响应。

即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

(发送消息就是函数调用)

【注意】

1.abstract修饰成员方法之后,这个类也必须使用abstract进行修饰

2.abstract修饰方法以后,不能有方法体(所以不能被实例化)。

3.凡是使用abstract修饰的类叫抽象类。abstract方法叫抽象方法

4.抽象类下面可以有非抽象方法。

5.在子类中,只要是抽象方法,必须去实现(无条件的实现,不然报错)。

6.抽象类(abstract)没有自己的类对象【重点】

7.有抽象方法的类必须是抽象类。但是抽象类下面可以没有抽象方法

抽象类的规则:
a、抽象类可以没有抽象方法,有抽象方法的类必须是抽象类
b、非抽象类继承抽象类必须实现所有抽象方法
c、抽象类可以继承抽象类,可以不实现父类抽象方法。
d、抽象类可以有方法实现和属性
e、抽象类不能被实例化
f、抽象类不能声明为final
g、抽象类可以有构造方法
abstract修饰的类叫抽象类,抽象类下面可以有非抽象方法,有抽象方法的类必须是抽象类。非抽象类继承抽象类必须实现所有抽象方法,而抽象类继承抽象类,可以不实现父类抽象方法。抽象类可以有方法实现和属性,也可以有构造方法,但是抽象类不可以被实例化,也不能声明为final

abstract修饰的成员方法,要求子类必须重写父类的方法,父类,又称匿名内部类,没有自己的类对象,抽象方法没有方法体。

package day10;

/**
 * abstract抽象类:abstract关键字修饰成员方法,要求子类必须重写父类的方法。
 */
abstract class demo_abstract {//demo_abstract就叫做抽象类,不可以被实例化

    abstract public void a();//a()叫做抽象方法

    public static void feichouxiangfangfa() {

    }//抽象类下面可以有非抽象方法。

    //抽象类(abstract)没有自己的类对象【重点】
    //有抽象方法的类必须是抽象类。但是抽象类下面可以没有抽象方法
//在子类中,只要是抽象方法,必须去实现(无条件的实现,不然报错)。
}
package day10;

/**
 * 在子类中,只要是抽象方法,必须去实现(无条件的实现,不然报错)。
 */
public class demo_abstract_main extends demo_abstract {
    @Override
    public void a() {
        System.out.println("子类必须重写了父类的方法");
    }
}
package day10;

public class Demo {
    public static void main(String[] args) {
        /**
         * 抽象类
         */
        demo_abstract_main demo_abstract_main = new demo_abstract_main();//抽象类的子类
       // System.out.println();
        demo_abstract_main.a();

        demo_abstract demo_abstract = new demo_abstract() {
            @Override
            public void a() {

                System.out.println("这个是匿名内部类,没有自己的类对象,用到了必须被重写");
            }
        };//父类,又称匿名内部类,没有自己的类对象
       }
       }

9. final关键字

1. 修饰成员变量:必须定义初始化的值,初始化后不能被修改。
2. 修饰局部变量:一旦被赋值,就无法被修改。
3. 修饰成员方法:该方法为最终方法,且只能被子类继承,但是不能被子类重写。
4. 修饰类:该类就转变为最终类,没有子类的类,且无法被继承。
5. 在方法参数中使用final,在该方法内部不能修改参数的值
(String类是java给封装好的类)

  1. 修饰成员变量:必须定义初始化的值,初始化后不能被修改。

  2. 修饰局部变量:使用final修饰的一旦被赋值,就无法被修改。

  3. 修饰成员方法:该方法为最终方法,且只能被子类继承,但是不能被子类重写。

  4. 修饰类:该类就转变为最终类,没有子类的类,fianl修饰的类无法被继承。

  5. 在方法参数中使用final,在该方法内部不能修改参数的值

(String类是java给封装好的类) final class TestFinal { final int num = 10; final public void test() { System.out.println(num); //num = 20; } } //class Son extends TestFinal { // // public void test () {} //} public class Demo1 { public static void main(String[] args) { final int num; num = 10; //num = 20; } }

10. interface关键字(接口)

1.接口下面可以声明成员属性,但是这个属性是static和final修饰的,省略了public static final
2.接口下面可以声明成员方法,但是方法必须是抽象的方法,省略了abstract,
3.接口不能有构造方法,也不能被实例化
4.定义一个接口使用interface,实现接口使implements,
一个接口可以继承多个接口,一个类可以实现多个接口,
抽象类实现接口可以不实现接口的方法,
在接口中定义的方法没有声明访问修饰符,
默认为public
5.java8新增
  default方法和static方法,这两种方法完全可以有方法体
  default方法属于实例,static方法属于类(接口)
  接口中的静态方法不会被继承,接口中的静态变量会被继承

接口下面不能实例化

【注意】:

1.接口下面可以声明成员属性,但是这个属性是static 和final修饰的,省略了public static final

2.接口下面可以声明成员方法,但是方法必须是抽象的方法,省略了abstract

3.jdk1.8新特性接口中允许使用default修饰方法。来完成对方法默认的定义。这个方法可以有方法体

4.使用implements这个关键字取实现接口

接口的使用规则:
(1)定义一个接口,使用interface关键字
(2)在一个接口中,只能定义常量、抽象方法,JDK1.8后可以定义默认的实现方法
(3)接口可以继承多个接口:extends xxx,xxx
(4)一个具体类实现接口使用implements关键字
(5)一个类可以实现多个接口
(6)抽象类实现接口可以不实现接口的方法
(7)在接口中定义的方法没有声明 访问修饰符,默认为public
(8)接口不能有构造方法
(9)接口不能被实例化
java8新增
(1)增加了default方法和static方法,这两种方法完全可以有方法体
(2)default方法属于实例,static方法属于类(接口)
(3)接口中的静态方法不会被继承,接口中的静态变量会被继承

package day10;

interface demo_interface_USB {
    public int a = 10;//定义了一个成员变量  省略了public static final
    public static final int b = 20;
    public void work1();//定义了一个成员方法,省略了abstract
    public void work2();
    //.jdk1.8新特性接口中允许使用default修饰方法。来完成对方法默认的定义。这个方法可以有方法体

    default public void tex(){
        System.out.println("default修饰的方法,默认的方法");
    }
    //使用implements这个关键字取实现接口
}
package day10;

public class demo_interface_main implements demo_interface_USB {
    @Override
    public void work1() {
        System.out.println("USB1接口插U盘");
    }

    @Override
    public void work2() {

        System.out.println("USB2接口插鼠标");
    }
}

10.1抽象类和接口的区别

1.成员方法:
抽象类可以同时包含抽象与非抽象的方法,不能有方法体,不能被实例化,而接口中,所有的方法隐含的都是抽象方法
2.类:
在抽象类中,只能继承一个抽象类,在子类中,只要是抽象方法,必须去实现,接口中,可以实现多个接口,必须实现接口声明的所有方法
3.成员变量:
抽象类可以包含非final的变量,接口中,都是默认的final变量
4.成员函数:
抽象类可以是private、protected、public,在接口默认都是public

abstract interface
成员方法 可以同时包含抽象与非抽象的方法,不能有方法体,不能被实例化 所有的方法隐含的都是抽象方法
只能继承一个抽象类,在子类中,只要是抽象方法,必须去实现 可以实现多个接口,必须实现接口声明的所有方法
成员变量 可以包含非final的变量 都是默认的final变量
成员函数 可以是private、protected、public 默认都是public

11. static关键字

static 静态

static 修饰的东西和对象无关

1.通过对象使用静态修饰的东西是有隐患的或者直接报错

修饰成员属性的时候:

类名.属性 ="";

static关键字的作用:方便在没有创建对象的情况下来进行调用(方法/变量)。
a、使用static关键字修饰一个属性:声明为static的变量实质上就是全局变量
b、使用static关键字修饰一个方法:在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法(类调用)
c、使用static关键字修饰一个类(内部类):
声明为static的方法有以下几条限制: 
它们仅能调用其他的static 方法,反过来是可以的。 
它们只能访问static数据。 
它们不能以任何方式引用this或super。
不允许用来修饰局部变量

11.1修饰成员变量

11.2修饰成员方法

static修饰的成员方法能不能使用类内非静态的成员变量和非成员方法??
	    不能
		非静态的成员方法和非静态的成员变量都是需要对象来进行调用的。
		但是静态方法中类的加载就已经加载了,早于对象的创建的。
static修饰成员变量时:
1.与对象一点关系没有,因为类对象保存在堆区,而静态的成员属性保存在数据区,这两个区域不相干的,
2.成员变量会随着类的.class文件加载而加载到内存中的数据区,创建的静态成员变量,运行过程优先级高于创建对象,当前数据区存储的静态成员变量伴随这整个程序的运行阶段,只要程序不退出,不销毁,他就一直存在。

static修饰成员方法时:
1.随着.class文件加载到内存中的代码区中并完成定义。这个时候没有对象的创建,只要代码不退出或者销毁,静态成员方法一直会在代码区存在
2.静态的成员方法中不能使用非静态的成员属性和非静态的成员方法
3.静态的成员方法是没有对象的,不能被重写,不能使用this关键字。因为this表示是调用当前方法的类对象。是直接使用类名.方法名调用即可,但是在静态方法中可以创建对象。

修饰成员变量 修饰成员方法
内存分析 在内存的数据区 加载后已经在内存的代码区中完成定义
加载形式 随着.class文件加载到内存中 随着.class文件加载到内存中
和类对象的关系 与对象一点关系没有,随着类的加载而加载,一处修改,处处受影响 完全摆脱类的约束,与对象一点关系没有
如何调用 通过类名.变量 通过类名.方法
注意 1.在代码运行过程中,已经销毁了所有的类对象。依然是可以通过类名调用静态的成员变量的2.创建的成员变量,运行过程优先级高于创建对象,当前数据区存储的静态成员变量伴随这整个程序的运行阶段,只要程序不退出,不销毁,他就一直存在。3.保存区域:类对象保存在堆区,而静态的成员属性保存在数据区,这两个区域不相干的。 1.这个时候没有对象的创建,只要代码不退出或者销毁,静态成员方法一直会在代码区存在2.静态的成员方法中不能使用非静态的成员属性和非静态的成员方法3.静态的成员方法是没有对象的,不能被重写,不能使用this关键字。因为this表示是调用当前方法的类对象。是直接使用类名5.静态方法中可以创建对象。
class SingDog {

    String name;
    int age;
    static String text="hujh";//也允许不赋值

    public SingDog() {
    }
    public void textt(){
        System.out.println("成员方法");
        System.out.println(age);//可以调用
        SingDog.tex();//可以调用静态方法
    }
    public static void tex(){
        System.out.println(SingDog.text);
        //System.out.println(age);静态方法中不能调用非静态的成员属性和成员方法
        System.out.println("静态成员方法");
       // SingDog.textt();//不可以调用非静态的方法
    }
}
public class Static_method {
    public static void main(String[] args) {
        //调用静态方法,强烈推荐
        SingDog.tex();
        System.out.println(SingDog.text);
        
        //调用成员方法,不推荐
        SingDog singDog = new SingDog();
        singDog.textt();
    }
}

11.3static静态代码块

类文件只要加载,静态代码块一定加载。

class Demo {
    //静态代码块


    //对对象加上静态修饰
    static Demo demo1 = new Demo();
    static Demo demo2 = new Demo();
    //构造代码块
    {
        System.out.println("这个是demo的构造代码块");
    }
    static {
        System.out.println("demo的静态代码块");
    }
    public  Demo() {
        System.out.println("demo的构造方法");
    }
   public static void main(String[] args) {
       Demo demo = new Demo();
   }
}

代码的运行效果:

1.顺序原则

2.执行的优先级

3.语法的要求

执行者: static Demo demo1 = new Demo();

构造代码块

构造方法

执行者: static Demo demo2 = new Demo();

构造代码块

构造方法

执行者:类内的静态的代码块

demo的静态代码块

执行者:主函数中的

Demo demo = new Demo();

构造代码块

构造方法

原则:

1.代码执行最基本的原则,从上到下的执行原则

2.执行构造方法,一定会有构造代码块

3.构造代码块的优先级最高

11.3.1构造方法

public Hello() {

}

关于构造方法要注意以下几点:

1.对象一创建,就会调用与之对应的构造方法。也就是说,不建立对象,构造方法不执行

2.对对象进行初始化的

3.一个对象创建,构造函数只运行一次,再创建一个对象,再运行一次

11.3.2构造代码块

{代码块}

关于构造代码块要注意以下几点:

1.构造代码块是给对象进行初始化的。

2.对象一建立就运行构造代码块。而且优先于构造方法。这个地方强调一下。有对象才能执行构造代码块。

类不能调用构造代码块。

11.3.3静态代码块

static {代码块}

关于静态代码块要注意以下几点:

1.static修饰的静态代码块没有对象的,他是随着类的加载而执行的。并且执行一次。并且优先于main主函数。具体来讲,静态代码块是由类来调用的。

类调用的时候,先执行静态代码块,然后再执行main主函数。

2.静态代码块就是对类进行初始化的。构造代码块是对对象进行初始化的。

3.静态代码中变量,是一个局部变量,和普通的局部没有任何区别

4.一个类中可以有多个静态代码块

11.3.4三者的执行优先级

对于一个类而言

1.先去执行静态代码块

2.执行构造代码块

3.执行构造方法

对于静态变量,静态的代码块,变量,代码块,构造方法。他们初始化的顺序:(静态变量,静态代码块)>(变量,代码块)>构造方法

12. this() & super()

this()只能在当前对象的构造方法中使用,且只能放在当前构造方法的第一行,也可以调用类对象的成员变量和成员方法,也可以操作当前类对象,也可以根据传参不同决定调用类内其他的构造方法,但不能调用本身的构造方法。
super()只能在子类的构造方法中的第一行使用。
也可以调用的是父类的成员变量和成员方法

12.1 this()

【注意】

  1. 在当前对象的构造方法中使用。

  2. 可以调用类对象的成员变量和成员方法,也可以操作当前类对象。

  3. this()在类内调用其他的构造方法。是根据传参不同决定调用哪个构造方法。

  4. 不能调用本身的构造方法。

5. this(实际参数),有且只能放在当前构造方法的第一行。

12.2 super() 鸡肋

如果子类中出现了和父类中同名的成员变量和成员方法,这个时候可以使用super关键字告知编译器。

可以理解为对父类的引用,使用super来调用父类的属性,方法,和构造方法

【注意】

  1. 只能子类的构造方法中。

  2. 必须在第一行。

  3. 也可以调用的是父类的成员变量和成员方法。

  4. super关键字还可以调用父类的构造方法。

13.匿名内部类

13.1基于abstract的匿名内部类

/*
* 我们要学习匿名内部类
*   没有名字的类,不是声明的时候没有类名,实例化的时候咱们可以不写变量的名字
* 按道理来讲应该继承
* */
abstract class AbstractTestType {
    abstract public void testInnerType();
}
class TestA extends AbstractTestType {

    @Override
    public void testInnerType() {
        System.out.println("一个类继承了AbstractTestType,调用这个方法");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        AbstractTestType att = new AbstractTestType() {
            @Override
            public void testInnerType() {
                System.out.println("匿名内部类对象调用该方法!!!");
            }
        };
        //匿名内部类的对象调用了方法!!!
        att.testInnerType();
        /*使用匿名内部类,并且创建一个对象,而这个对象也没有名字*/
        new AbstractTestType() {
            @Override
            public void testInnerType() {
                System.out.println("匿名内部类的匿名对象调用了这个方法");
            }
        }.testInnerType();

        test(new TestA());//low
        test(new AbstractTestType() {
            @Override
            public void testInnerType() {
                System.out.println("匿名内部类匿名对象直接操作方法的参数");
            }
        });
    }
    public static void test (AbstractTestType t) {
        t.testInnerType();
    }
}

13.2基于接口的匿名内部类

interface A {
    public void testInterface();
}
public class Demo2 {
    public static void main(String[] args) {
        A a = new A() {
            @Override
            public void testInterface() {
                System.out.println("匿名内部类的对象调用该方法");
            }
        };
        a.testInterface();

        new A() {
            @Override
            public void testInterface() {
                System.out.println("匿名内部类的匿名对象调用该方法");
            }
        }.testInterface();
    }
}

你可能感兴趣的:(java基础,java)