Java中的多态、抽象类、接口

1、包

  • 进行面对对象的编程时,一项最基本的考虑是:如何将发生变化的东西与保持不变的东西分隔开,这一点对于库来说是非常重要的。那个库的用户必须能依赖自己使用的那部分。如何将组件绑定到单独统一的库单元里。这是通过Java中的关键字package(打包)来实现的
  • 我们用import关键字导入一个完整的库时,就会获得“包”(Package)
    例如:import java.util.*
    1、它的作用是导入完整的实用工具(utity)库,该库属于标准Java开发工具包的一部分。由于Vector位于java.util里,所以现在要么指定完整名称”(可省略import语句),要么简单地指定一个因为import是默认的)
    2、若想导入单独一个类,可在import语句里指定那个类的名字:
    import java.util.Vector
    (现在,我们可以自由地使用vector,但是java.util 中的其他任何类仍是不可使用的。)
  • 在Java中:
    1、 为Java创建一个源码文件的时候,它通常叫作一个“编辑单元”(有时也叫作“翻译单元”)。每个编译单元都必须有一个以 .java 结尾的名字。
    2、而且在编译单元的内部,可以有一个公共(public)类,它必须拥有与文件相同的名字(包括大小写形式,但排除 .java 文件扩展名)。如果不这样做,编译器就会报告出错。
    3、每个编译单元内都只能有一个public类(同样地,否则编译器会报告出错)。那个编译单元剩下的类(如果有的话)可在那个包外面的世界面前隐藏起来,因为它们并非“公共”的(非public)而且它们由用于主public类的“支撑”类组成。
    4、编译一个Java文件时,我们会获得一个名字完全相同的输出文件。但对于Java文件中的每个类,它们都有 .Class 扩展名。因此,我们最终从少量的Java文件里有可能获得数量众多的 .class 文件。
    之前学C的时候,已经习惯编译器先分割出一种过渡形式( .obj 文件),再用一个链接器将其与其他东西封装到一起(生成一个可执行文件 .exe 文件),或者与一个库封装到一起(生成一个库)。但那并不是Java的工作方式。一个有效的程序就是一系列 .class 文件,它们可以封装和压缩到一个JAR文件里(使用Java11提供的jar工具)Java解释器负责对这些文件的寻找、装载和解释。
  • 若在一个文件的开头使用下述代码:package mypackage;
    那么语句必须作为文件的第一个非注释语句出现,该语句的作用是指出这个编译单元属于名为mypackage的一个库的一部分。或者换句话说,它表明这个编译单元内的public类名位于mypackage这个名字的下面。如果其他人想使用这个名字,要么指出完整的名字,要么与联合使用 import 关键字(使用前面给出的选项)。注意根据Java包(封装)的约定,名字内的所有字母都应小写,甚至那些中间单词亦要如此。
  • 作为一名库使用与设计者,一定要记住 pakage 和 import 关键字允许我们做的事情就是分割单个全局命名空间,保证我们不会遇到名字的冲突—无论有多少人使用因特网,也无论多少人用Java编写自己的类。根据约定,** package 名的第一部分是类创建的因特网域名,将公司的因特网域名以逆序的形式作为包名,并且对于不同的项目使用不同的子包。**,因为它一定是独一无二的
  • 如果没有指定 public 或 private 这个部分(类、方法或变量)可以被同一个包中的所有方法访问。

2、多态

  • 某一个事物,在不同时刻表现出来的不同状态
    Cat c=new Cat();
    Animal a=new Cat();
  • 多态前提
    1、要有继承关系。
    2、要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
    3、要有父类引用指向子类对象。
    父 f = new 子();
  • 多态中的成员访问的特点:
    a:成员变量
    编译看左边,运行看左边。
    b:构造方法
    创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
    c:成员方法
    编译看左边,运行看右边。
    d:静态方法
    编译看左边,运行看左边。
    (静态和类相关,算不上重写,所以,访问还是左边的)
  • 多态的好处
    a:提高了代码的维护性(继承保证)
    b:提高了代码的扩展性(由多态保证)
    ——这里举一个非常典型的例子:
class A {
		public void show() {
			show2();
		}
		public void show2() {
			System.out.println("我");
		}
	}
	class B extends A {
		public void show2() {
			System.out.println("爱");
		}
	}
	class C extends B {
		public void show() {
			super.show();
		}
		public void show2() {
			System.out.println("你");
		}
	}
	public class DuoTaiTest4 {
		public static void main(String[] args) {
			A a = new B();
			a.show(); // 爱 
			
			B b = new C();
			b.show(); // 你 
		}
	}

【分析上面的程序,发现首先创建了一个B类的对象,但是是用A类的引用来接收,父类的引用指向子类的对象,这就是多态的形式。
因为使用这个引用去调用方法,因此这里应该遵循编译看左,执行看右。也就是编译器回首先查看A类里面有没有这个方法,然后再去执行B类里面的这个方法。显然,A里面存在这个方法,并且执行结果为打印一个“我”,但是最终结果并不是这个,B类里面没有重写A里面的show(),因此他直接继承了这show()方法,由于这个方法内部又调用了一个被重写过后的方法show2(),因此B类里面的show()方法执行结果为“爱”。
接下来又出现了多态,这次是使得B类的引用指向C类的对象,因为B本身继承于A,虽然B里面没有定义方法show(),但是他继承了A里面的方法,因此编译看左不会报错;执行看右边,发现C对B中的方法进行了重写,如果此时在C中show()方法前加@override标签发现不报错,C中的这个方法是调用B中的show(),B中的show()应该是:
public void show() {
show2();
}
这里的show2()当然指的是B中的方法,C调用了这个方法,但是由于show2()又被重写,因此C中执行的结果为在控制台输出“你”。这个例子非常典型,刚开始自己也没有想明白,现在再看,发现程序运用的就是多态的思想。】

  • 通过多态的弊端——
    引出问题:不能使用子类特有的功能
    解决方法:把父类的引用强制转换为子类的引用(向下转型)
public class MyTest {
    public static void main(String[] args) {
        Fu fu = new Zi();
        System.out.println(fu.num);//20
        fu.show(); //zi show
        Zi zi= (Zi) fu; //向下转型
        System.out.println(zi.num);//200
        zi.teyou();
    }

}
class Fu{
    int num=20;
    public void show(){
        System.out.println("父类的show");
    }
}
class Zi extends Fu{
    int num=200;

    @Override
    public void show() {
        System.out.println("子类的show");
    }
    public void teyou(){
        System.out.println("子类特有的方法");
    }
}

执行结果为:
20
子类的show
200
子类特有的方法

3、抽象类

  • 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
  • 抽象类特点:
    1、抽象类和抽象方法必须用abstract关键字修饰
    抽象类格式: abstract class 类名 {}
    抽象方法格式: public abstract void eat();
    2、抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
    3、抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?用于子类访问父类数据时的初始化
    4、抽象类不能直接实例化那么,抽象类如何实例化呢?
    按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    5、抽象类的子类,要么是抽象类,要么重写抽象类中的所有抽象方法
  • 抽象类的成员特点:
    成员变量——既可以是变量,也可以是常量。
    构造方法——有。用于子类访问父类数据的初始化。
    成员方法——既可以是抽象的,也可以是非抽象的。
    抽象方法——强制要求子类做的事情。
    非抽象方法——子类继承的事情,提高代码复用性。
public static void main(String[] args) {
        //抽象类,不能创建对象,只能通过子类创建对象间接地创建自己的对象
       // Aniaml aniaml = new Aniaml();
        Aniaml an = new Cat();
        an.eat();
        an.sleep();
        an=new Dog();
        an.eat();
        an.sleep();
 //为什么要引入抽象类的概念?
 //我们将多个子类的共性功能向上抽取到父类当中,我们父类肯定知道这些子类的共性功能,但是父类没有必要知道,这些共性功能的具体实现是怎么样,因为也没有必要知道,因为每个子类都有差异性,如果我在父类中,给出了这个功能的具体实现,那么每个子类的这个功能,其实都是一样的,并不能体现出每个子类对这个功能的具体实现,所以父类,只需要给出这个功能的声明,而不需要给出功能的具体实现,具体实现,交由子类根据自身的差异去实现。
    }
//抽象类
public abstract class Aniaml {
    //抽象方法
    public abstract void eat();

    public abstract void sleep() ;
}
public class Cat extends Aniaml{

    public void catchMouse(){
        System.out.println("抓老鼠");
    }
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    @Override
    public void sleep() {
        System.out.println("猫喜欢白天睡觉");
    }
}
public class Dog extends Aniaml{
    public void lookDoor(){
        System.out.println("看门");
    }
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    @Override
    public void sleep() {
        System.out.println("狗躺着睡觉");
    }
}
  • abstract不能和哪些关键字共存?
    private 冲突
    【abstract本身就是抽象的意思,它需要子类来实现它里面的方法,如果你将父类里面的方法设为私有的,子类都不能继承,何谈去实现父类的方法】
    final 冲突
    【final关键字修饰的方法本身就不能被重写,如果父类里面的抽象方法是final的,子类就没有办法进行重写;如果父类本身就是final修饰,子类都没办法继承,也就没有办法去重写】
    static 不能共存 ,无意义
    【父类如果有staitic修饰的方法,意味着这个方法是随着类的产生而产生,可以直接使用类名来调用,也就是说静态方法并不会依赖于继承关系,所以这两个关键字共存没有意义】

4、接口

  • 为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现。比如马戏团里的猫类与狗类可能会有区别于普通猫狗的本领,将来那些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
  • 接口特点
    1、接口用关键字interface表示
    格式: interface 接口名 {}
    2、类实现接口用implements表示
    格式: class 类名 implements 接口名 {}
    3、接口不能实例化
    那么,接口如何实例化呢 ? 按照多态的方式来实例化。
    4、接口的子类
    可以是抽象类。但是意义不大。
    可以是具体类。要重写接口中的所有抽象方法。
  • 接口成员特点
    成员变量;只能是常量,并且是静态的。——默认修饰符:public static final
    (建议:自己手动给出)
    构造方法:接口没有构造方法。
    成员方法:只能是抽象方法。——默认修饰符:public abstract
    (建议:自己手动给出)
public class MyTest {
    public static void main(String[] args) {
        //接口:定义事务的额外的扩展的功能,接口也会定义规范和规则
        //interface
        //接口不能创建对象
        //MyInterface 就是 Cat 的父接口  父接口与子类的关系 叫做实现关系implements
        MyInterface my = new Cat(); //多态
        my.jump();
        Cat cat= (Cat) my;
        cat.eat();
        cat.catchMouse();
    }
}
public class Cat implements MyInterface{
    public void eat(){
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
    @Override
    public void jump() {
        System.out.println("经过不断的练习,猫学会了跳高");
    }
}
public class Dog implements MyInterface{
    @Override
    public void jump() {
        System.out.println("狗经过了练习,学会了跳高");
    }
}
//interface 定义接口
//接口中的方法是抽象的,不给出功能的具体实现
public interface MyInterface {
    //提供跳高的功能
    public abstract void jump();
}
程序输出:
经过不断的练习,猫学会了跳高
猫吃鱼
猫抓老鼠

5、类、抽象类、接口

  • 类与类:
    继承关系,只能单继承,可以多层继承。
  • 类与接口:
    实现关系,可以单实现,也可以多实现。
  • 接口与接口:
    继承关系,可以单继承,也可以多继承。
  • 抽象类与接口的区别:
    1、成员区别
    抽象类:
    成员变量:可以变量,也可以常量
    构造方法:有
    成员方法:可以抽象,也可以非抽象
    接口:
    成员变量:只可以常量
    成员方法:只可以抽象
    2、关系区别
    类与类:继承,单继承
    类与接口:实现,单实现,多实现
    接口与接口:继承,单继承,多继承
    3、设计理念区别
    抽象类——被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
    接口——被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
public class MyTest {
    public static void main(String[] args) {
       /* 
        动物类:姓名,年龄,吃饭,睡觉。
        动物培训接口:跳高
        猫继承动物类
        狗继承动物类
        部分猫继承猫类并实现跳高接口
        部分狗继承狗类并实现跳高接口*/
        Animal an = new 旺财();
        an.name="旺财";
        an.age=2;
        System.out.println(an.name);
        System.out.println(an.age);
        an.sleep();
        an.eat();
        旺财 wc= (旺财) an;
        wc.lookDoor();
        高菲狗 gf = new 高菲狗();
        an=gf;
        an.name="高菲";
        an.age=3;
        System.out.println(an.name);
        System.out.println(an.age);
        an.eat();
        an.sleep();
        JumpInterface jumpInterface= gf;
        jumpInterface.jump();
        System.out.println("----------------");
        Animal an1 = new 加菲猫();
        an1.name="加菲猫";
        an1.age=4;
        System.out.println(an1.name);
        System.out.println(an1.age);
        an1.sleep();
        an1.eat();
        加菲猫 jf= (加菲猫) an1;
        jf.catchMouse();
        狸花猫 lh = new 狸花猫();
        an1=lh;
        an1.name="狸花猫";
        an1.age=6;
        System.out.println(an1.name);
        System.out.println(an1.age);
        an1.eat();
        an1.sleep();
        JumpInterface jumpInterface1= jf;
        jumpInterface1.jump();
    }
}
public interface JumpInterface {
    void jump();
}
public abstract class Animal {
    String name;
    int age;
    public abstract void eat();
    public abstract void sleep();
}
public class Cat extends Animal{
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
    @Override
    public void eat() {
        System.out.println("猫爱吃鱼");
    }
    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
public class Dog extends Animal{
    public void lookDoor(){
        System.out.println("狗看门");
    }
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    @Override
    public void sleep() {
        System.out.println("狗躺着睡觉");
    }
}
public class 加菲猫 extends Cat implements JumpInterface{
    @Override
    public void eat() {
        System.out.println("加菲猫吃小鱼干");
    }
    @Override
    public void jump() {
        System.out.println("加菲猫经过不断的学习,学会了跳高");
    }
}
public class 旺财 extends Dog{
    @Override
    public void eat() {
        System.out.println("旺财吃狗粮");
    }
}
public class 狸花猫 extends Cat{
    @Override
    public void eat() {
        System.out.println("狸花猫吃老鼠");
    }
}
public class 高菲狗 extends Dog implements JumpInterface{
    @Override
    public void eat() {
        System.out.println("高菲吃狗罐头");
    }

    @Override
    public void jump() {
        System.out.println("高菲学会了跳高");
    }
}
输出结果为:
旺财
2
狗躺着睡觉
旺财吃狗粮
狗看门
高菲
3
高菲吃狗罐头
狗躺着睡觉
高菲学会了跳高
----------------
加菲猫
4
猫白天睡觉
加菲猫吃小鱼干
抓老鼠
狸花猫
6
狸花猫吃老鼠
猫白天睡觉
加菲猫经过不断的学习,学会了跳高

6、方法参数类型以及返回值类型问题

1、形参为类类型:
public class MyTest2 {
    public static void main(String[] args) {
        //一个方法的形参一个类类型,就传递该类的对象
        Student student = new Student();
        test(student,20);
        System.out.println(student.age);
        student.show(new Student(),21);
        System.out.println((new Student()).age);
    }
    public static void test(Student student, int a){
        student.age=a;
    }
}
class Student{
    int age=24;
    public void show(Student student,int a){
        student.age=a;
    }
}
输出结果为:
20
24
2、形参为抽象类类型
public class MyTest {
    public static void main(String[] args) {
        //方法的形参要一个抽象类类型,就传递该抽象类的子类对象
        Son son = new Son();
        test(son,15);
    }
    public static void test(Teacher teacher,int num){
    //这里实质上是多态的形式,使得父类的引用接收子类的对象
        teacher.num=num;//成员变量执行编译都看父类
        teacher.show(num);//成员方法编译看父类,执行看子类
    }
}
abstract class Teacher{
        int num=100;
        public abstract void show(int num);
}
class Son extends Teacher{
    int num = 2;
    @Override
    public void show(int num) {
        System.out.println(this.num);//2
        System.out.println(num);//15
        System.out.println(super.num);//15
    }
} 
//因为程序在执行test()方法时,就已经将父类中的成员变量进行了重新赋值,因此输出的super().num是赋值后的值
3、形参为接口类型
public class MyTest {
    public static void main(String[] args) {
        //方法的形参需要一个接口类型,传一个实现该接口的子类对象
        MyClass myClass = new MyClass();
        test(myClass,60);
        System.out.println(Myinterface.num);
    }
    public static void test(Myinterface myinterface,int num){
        myinterface.show(num);
    }
}
interface Myinterface{
//接口中只有静态自定义常量
   public static final int num=200;
    public abstract void show(int num);
}
class MyClass implements Myinterface{
    int num=10;
    @Override
    public void show(int num) {
        System.out.println(this.num);
    }
}
输出结果为:
10
200
4、方法的返回值为类类型
public class MyTest {
    public static void main(String[] args) {
        Student student = new Student();
        Student student1 = test(student, 1);
        System.out.println(student.num);
        System.out.println(student1.num);
        System.out.println("----------------------------------");
        student.show(student,2);
        student1.show(student,3);
        System.out.println(student.num);
        System.out.println(student1.num);
    }
    public static Student test(Student student,int num){
        student.num=num;
        //一个方法的返回值类型,要一个类类型,就返回该类的一个对象
        return new Student();
    }
}
class Student{
    int num=4;
    public void show(Student student,int num){
        this.num=num;
    }
}
输出结果为:
1
4
----------------------------------
2
3
5、方法的返回值为抽象类类型
public class MyTest {
    public static void main(String[] args) {
        MyClass myClass = test(new Zi(), 1);
        myClass.show(2);
    }
    public static MyClass test(MyClass myClass,int num){
        myClass.num=num;
        //当一个方法的返回值类型为抽象类类型,就返回一个该抽象类的子类对象
        return new Zi();
    }
}
abstract class MyClass{
    int num=3;
    public abstract void show(int num);
}
class Zi extends MyClass{
    @Override
    public void show(int num) {
        System.out.println(this.num);
        System.out.println(super.num);
    }
}
输出结果为:
3
3
6、方法的返回值为接口类型
public class MyTest3 {
    public static void main(String[] args) {
        MyInterface test = test(1);
        test.show(2);
    }
    //一个方法的返回值类型要一个接口类型,就返回一个实现该接口的子类对象
    public static MyInterface test(int num){
        System.out.println(num);
        return new MyDemo();
    }
}
interface MyInterface{
    void show(int num);
}
class MyDemo implements MyInterface{
    @Override
    public void show(int num) {
        System.out.println(num); 
    }
}
输出结果为:
1
2
7、链式编程
public class MyTest {
    public static void main(String[] args) {
        Student student = new Student();
        Student student1 = student.getStudent(student, 1);
        Student student2=student1.show();
        System.out.println(student2.num);
        System.out.println("---------------------------");
        //以上的代码可以用链式编程来调用
        //链式编程:当你调用完一个方法后,这个方法的返回值是一个对象。那么你就可以紧接着打点。在去调用这个对象的方法
        int a= new Student().getStudent(new Student(), 2).show().num;
        System.out.println(a);
    }
}
class Student{
    int num=3;
    public Student getStudent(Student student,int num){
        student.num=num;
        return new Student();
    }
    public Student show(){
       // System.out.println(num);
        return this;
    }
}
输出结果为:
3
---------------------------
3

7、权限修饰符

针对类内的每个成员的每个定义,Java访问指示符public、protected、private都置于它们的最前面——无论他们是一个数据成员还是一个方法,每个访问指示符都只控制着对那个特定定义的访问

1、“友好的”

如果跟本不指定任何访问指示符,默认的访没有关键字,但他通常称为“友好”访问,这意味着当前包内的所有类都能“友好的”访问该成员,但对包外的类,它是私有的;因此我们说友好元素拥有“包访问”权限

2、public:接口访问

使用public关键字时,它意味着紧随在public之后的成员声明适用于外界所有类,特别是适用于使用库的库成员。

3、private:不能接触!

该关键字意味着除非那个特定的类,而且从那个类的方法里,否则没有人能访问那个成员,同一个包内不同类内也不行。使用该关键字还是很有用处的,我们应该根据自己的需求去设计程序

4、protected:“有好的一种”

与继承的概念相联系,只有子类继承于父类才可以访问父类里面的protected成员,若新建一个包,并从另一个包内的某个类里面继承,则能访问的就是原来包内的public成员与protected成员

8、内部类

  • 将一个类的定义置于另一个类中,这就叫做“内部类”,可以利用内部类对那些逻辑上相互联系的类进行分组,并可以控制一个类在另一个类中的可见性
  • 根据内部类的定义位置不同,可将它分为:
    ——成员内部类和局部内部类
  • 内部类访问特点
    1、内部类可以直接访问外部类的成员,包括私有。
    2、外部类要访问内部类的成员,必须创建对象。
  • 如何在测试类中直接访问内部类的成员?
    格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
//成员内部类
public class MyTest {
    class Contents{
        private int i=1;
        public int value(){
            return i;
        }
    }
    class Destination{
        private String label;
        Destination(String whereTo){
            label=whereTo;
        }
        String redLabel(){
            return label;
        }
    }
    public void ship(String dest){
        Contents c=new Contents();
        Destination d=new Destination(dest);
    }
    public static void main(String[] args) {
        MyTest p=new MyTest();
        p.ship("Tanzania");
    }
}
//一个外部类拥有特殊的方法,他会返回一个内部类的引用
public class MyTest {
    class Contents{
        private int i=1;
        public int value(){
            return i;
        }
    }
    class Destination{
        private String label;
        Destination(String whereTo){
            label=whereTo;
        }
        String redLabel(){
            return label;
        }
    }
    public Destination to(String s){
        return new Destination(s);
    }
    public Contents cont(){
        return new Contents();
    }
    public void ship(String dest){
        Contents c=new Contents();
        Destination d=new Destination(dest);
    }
    public static void main(String[] args) {
        MyTest p=new MyTest();
        p.ship("Tanzania");
        MyTest q=new MyTest();
        MyTest.Contents c=q.cont();
        MyTest.Destination d=q.to("Borneo");
    }
}
//局部内部类
public class MyTest {
    public static void main(String[] args) {
        //局部内部类:把内部类定义到了外部类的局部位置(方法中)
        //内部类可以直接范围外部类的成员包括私有的。
        //局部内部类,外界无法直接创建其对象
        new Outer().waiShow();
    }
}
class Outer {
    int num = 12;
    private double aa = 3.14;
    public void haha() {
        System.out.println("哈哈");
    }
    public void waiShow() {
        //定义局部内部类
        class Inner {
            int c = 2;
            public void neiHaha() {
                System.out.println("这是局部内部类的方法");
            }
            public void neiTest() {
                System.out.println(num);
                System.out.println(aa);
                waiSiyou();
            }
        }
        //创建内部类对象
        Inner inner = new Inner();
        inner.neiHaha();
    }
    private void waiSiyou() {
        System.out.println("这是外部类私有的方法");
    }
}
输出结果为:
这是局部内部类的方法

可以发现使用内部类是从两方面考虑:
1、正如上面展示的,我们希望以实行某种形式接口,使它能创建和返回一个句柄
2、要解决一个复杂的问题,并希望创建一个类,用来辅助自己的程序设计,同时不愿意把它公开

9、匿名内部类

  • 联系之前的匿名对象,可以得知匿名内部类是一个没有名字的内部类,匿名内部类的本质是一个对象,是实现该接口或继承了该抽象类的子类对象,前提是有一个接口或者抽象类
//接口:
public class MyTest2 {
    public static void main(String[] args) {
      new MyInterface(){
          @Override
          public void show() {
              System.out.println("show");
          }
      }.show();
    }
}
interface MyInterface{
    void show();
}
输出结果为;
show

抽象类:
public class MyTest {
    public static void main(String[] args) {
       new Fu(){
           @Override
           public void hehe() {
               System.out.println("呵呵1");
           }
           @Override
           public void haha() {
               System.out.println("哈哈1");
           }
       }.haha();
        new Fu() {
            @Override
            public void hehe() {
                System.out.println("呵呵2");
            }
            @Override
            public void haha() {
                System.out.println("哈哈2");
            }
        }.hehe();
    }
}
abstract  class Fu{
    public abstract void hehe();
    public abstract void haha();
}
执行结果为:
哈哈1
呵呵2
  • 匿名类中的this关键字:
interface Inter {
    public static final int a = 5 ;
    public abstract void show();
}
public class MyTest {
    public static void main(String[] args) {
        new Inter() {
            public void show() {
                //this 代表匿名内部类
                System.out.println(this.a);//23
            }
        }.show();
    }
}
输出结果为:
5
  • 这里加一道当时没有做出来的题目
//	要求在控制台输出”HelloWorld”
interface Inter {
    void show();
}
class Outer {
    public static Inter method(){
        return new Inter(){
            @Override
            public void show() {
                System.out.println("Hello World!");
            }
        };
    }
}
class OuterDemo {
    public static void main(String[] args) {
        Outer.method().show();
    }
}

总结:这部分面对对象的知识概念较多,而且有时候容易搞混,目前发现自己只能理解这些概念并举一些很简单的例子,还没能达到自己设计程序的同时将这些思想运用进去,但是熟能生巧,我希望自己以后在多敲代码的同时能够用心体会这部分内容。

发布了13 篇原创文章 · 获赞 8 · 访问量 398

猜你喜欢

转载自blog.csdn.net/weixin_45082647/article/details/103706406
今日推荐