Java学习记录 Day8(abstract、接口、内部类)

Day 8

2019年4月14日。
这是我学习Java的第八天。
这一天,我学到了以下的知识。

abstract

抽象的,可以修饰类,修饰方法。

特点:

  1. 一旦一个类中,有了抽象方法,此类必须为抽象类或接口类。抽象类可以有非抽象方法
  2. 抽象类不能直接创建对象,可以采用多态间接的去实例化抽象类
  3. 抽象类,就是被abstract所修饰的类,父类将所有的子类的共性功能向上抽取后,父类并不知道每个子类对这个共性功能的具体实现,所以没必要在父类中,给出共性功能的具体实现,而是给出声明即可。所谓给出功能的声明,就是将此功能抽象出来,然后强制子类必须重写抽象的功能
  4. 抽象类的子类,要么重写父类的所有抽象方法,要么自己也是抽象类
  5. 抽象类中有构造方法,用来让子类初始化父类
  6. abstract不能和private、final、static共存

接口

用来定义一些扩展功能,哪些事物将来要具备这个功能,就可以实现这个接口,然后对功能做出具体的实现(定义一些规范)。

特点:

  1. 接口不能new对象

  2. interface可以定义接口,implements可以实施接口

  3. 接口中成员变量的特点:接口中的成员变量全都是静态的公共常量(有默认的修饰符 public static final)

    接口中成员方法的特点:只能是抽象方法(默认修饰符 public abstract)

    接口中构造方法的特点:接口中没有构造方法

  4. 类与类,类与接口,接口与接口的关系

    a:类与类:
    继承关系,只能单继承,可以多层继承。

    b:类与接口:
    实现关系,可以单实现,也可以多实现。
    并且还可以在继承一个类的同时实现多个接口。

    c:接口与接口:
    继承关系,可以单继承,也可以多继承。

  5. 抽象类和接口的区别

    A:成员区别
    抽象类:
    成员变量:可以变量,也可以常量
    构造方法:有
    成员方法:可以抽象,也可以非抽象
    接口:
    成员变量:只可以常量
    成员方法:只可以抽象

    B:关系区别
    类与类
    继承,单继承
    类与接口
    实现,单实现,多实现
    接口与接口
    继承,单继承,多继承

    C:设计理念区别
    抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
    接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。

注意:JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用

传参和返回值

  • 传参
    - 形式参数是基本类型,要的是该类型的成员
    - 形式参数是类名,要的是该类的对象
    - 形式参数是抽象类名,要的是该抽象类的子类对象
    - 形式参数是接口类型,要的是该接口的子类对象

  • 返回值
    - 返回值类型是基本类型,返回的是该类型的成员
    - 返回值类型是类名,要的是该类的一个对象
    - 返回值类型是抽象类名,要的是该抽象类的一个子类对象
    - 返回值类型是接口类型,要的是该接口的一个子类对象

链式编程

当调用完一个方法后,方法的返回值又是一个对象,那么就可以紧接着打点再去调用对象的方法。

有关链式编程的例子:

public class MyTest {
    public static void main(String[] args) {
        //链式编程
        //Student student = new Student();
        //Student student1 = student.getStudent(new Student(), 100);
        //student1.show(109);
        //链式编程:当你调用完一个方法之后,方法的返回值又是一个对象,那么你就可以紧接着打点再去调用对象的方法
        Student student = new Student();

        new Student().getStudent(student, 100).show(109);

        System.out.println(student.num); //
    }
}


class Student {
    int num = 10;

    public Student getStudent(Student stu, int num) {
        stu.num = num;

        return this;
    }

    public void show(int num) {
        this.num = num;
    }
}

package

用来解决同一个路径下不能存在同名文件的问题,实质就是文件夹(package)。

格式:package 包名;// 多级包用,分开即可

定义包的注意事项:

  1. package语句必须是程序的第一条可执行的代码
  2. package语句在一个java文件中只能有一个
  3. 如果没有package,默认表示无包名

import

不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能(import)。

格式:import 包名;// 这种方式导入是到类的名称。 虽然可以最后写*,但是不建议。

常见的修饰符总结

四种常见修饰符( private(私有的) , 默认 , protected(受保护的) , public(公共的) )的访问权限如下所示:

修饰符\路径 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private(私有的)
默认
protected(受保护的)
public(公共的)

在Java中,修饰符的运用如下所示:

A:修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract

B:类:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public

C:成员变量:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多的就是:private

D:构造方法:
权限修饰符:private,默认的,protected,public
用的最多的就是:public

E:成员方法:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多的就是:public

F:除此以外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final

内部类

将一个类定义到另一个类的内部,那么这个类就叫做内部类。根据定义的位置不同,可以分为成员内部类和局部内部类。

  • 成员内部类
    - 定义:在外部类的成员位置定义的类,被称为成员内部类。
    - 若想在测试类中直接访问内部类,需要在测试类中定义内部类对象。
    格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象
    - 成员内部类的修饰符:private(为了保证数据的安全性),static(为了方便访问数据)。注意事项:静态内部类访问的外部类数据必须用静态修饰,且成员方法可以是静态的也可以是非静态的。
    若成员内部类被静态修饰,访问的格式为:外部类名.内部类名 对象名 = new 外部类名.内部类名();
    - 成员内部类的面试题
    要求:使用已知的变量,在控制台输出30,20,10。
class Outer {
		public int num = 10;
		class Inner {
			public int num = 20;
			public void show() {
				int num = 30;
				System.out.println(?); // num
				System.out.println(??); // Inner.this.num
				System.out.println(???); // Outer.this.num
			}
		}
	}
	class InnerClassTest {
		public static void main(String[] args) {
			Outer.Inner oi = new Outer().new Inner();
			oi.show();
		}	
	}
  • 局部内部类
    - 定义:在外部类的局部位置定义的类,被称为局部内部类。
    - 局部内部类可以直接访问外部类的成员,包括私有。
    外部类想要访问局部内部类的成员,要先创建内部类的对象,通过对象调用内部类方法,来使用局部内部类的功能。
    - 局部内部类想要访问外部类的局部变量,必须要用final修饰(因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。JKD1.8以后会默认加上final)。
    - 匿名内部类:是局部内部类的简写。本质上是一个对象,是实现了该接口或继承了该抽象类的子类对象。可以给匿名内部类起名,以此可以调用类中的多个成员方法,并作为参数返回。
    格式:new 类名或者接口名(){ 重写方法; } ;

类中定义接口

在外部类中定义一个接口,并且以接口的形式在测试类中调用外部类的接口

代码如下:

public class MyTest {
    public static void main(String[] args) {
        //间接方式
        Outer outer = new Outer();
        outer.waiShow();
        //直接方式

        new Outer.Inner() {
            @Override
            public void show() {
                System.out.println("重写了接口中的show方法2222");
            }
        }.show();

       Outer.Inner inner= new Outer.Inner() {
            @Override
            public void show() {
                System.out.println("重写了接口中的show方法2222");
            }
        };

       inner.show();
       inner.show();
    }

}

class Outer{
    //成员内部接口
    interface Inner{
        void show();
    }

    public void waiShow(){
        new Inner(){
            @Override
            public void show() {
                System.out.println("重写了接口中的show方法");
            }
        }.show();

    }
}

猜你喜欢

转载自blog.csdn.net/qq_41151659/article/details/89331500
今日推荐