javaSE基础知识——day11 抽象类abstract关键字、接口及接口与类的关系、pckag/import/ 权限修饰符/内部类/匿名内部类/object

Day11以及Day10回顾JAVASE基础知识

抽象类

  • 抽象类的概述
    回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
    为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。
    所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
    同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
    在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。

  • 抽象类的特点
    a:抽象类和抽象方法必须用abstract关键字修饰
    抽象类格式: abstract class 类名 {}
    抽象方法格式: public abstract void eat();
    b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
    c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
    用于子类访问父类数据时的初始化
    d:抽象类不能直接实例化那么,抽象类如何实例化呢?
    按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    e:抽象类的子类
    要么是抽象类
    要么重写抽象类中的所有抽象方法

  • 抽象类的成员特点
    a:成员变量:既可以是变量,也可以是常量。
    b:构造方法:有。
    用于子类访问父类数据的初始化。
    c:成员方法:既可以是抽象的,也可以是非抽象的。

  • 抽象类的成员方法特性:
    a:抽象方法 强制要求子类做的事情。
    b:非抽象方法 子类继承的事情,提高代码复用性。

案例

//一旦一个类中,有了抽象方法,此类必须为抽象类

public abstract class Animal {
    public Animal() {
        System.out.println("父类的构造方法执行了");
    }

    //abstract 抽象的,可以修饰类,修饰方法
    public abstract void eat(); //抽象方法,此方法没有方法实现

    public abstract void sleep();
    //抽象类中既可以有抽象方法,也可以非抽象方法
    public void show(){
        System.out.println("这是父类的一个非抽象方法");
    }

}


class Cat extends Animal{


    @Override
    public void eat() {
        System.out.println("猫爱吃鱼");

    }

    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
public class MyTest {
    public static void main(String[] args) {
      //  new Animal();//抽象类不能直接创建对象
        //我们可以采用多态间接的去实例化抽象类
        Animal an=new Cat();
        an.eat();
        an.sleep();
        an.show();
    }
}

注意:
抽象类不能直接创建对象
我们可以采用多态间接的去实例化抽象类

  • 抽象类理解:就是被abstract所修饰的类,父类将所有子类的共性功能向上抽取后,他并不知道,每个子类对这个共性功能的具体实现,所以没有必要在父类中,给出共性功能的具体实现,而是给出声明即可,所谓给出功能的声明,就是将此功能抽象出来,然后强制子类必须重写,抽象的功能。
  • 抽象类注意事项:
    一旦一个类中,有了抽象方法,那么此类必须为抽象类
    一个抽象类中可以没有抽象方法
    抽象类中既可以有抽象方法,也可以有非抽象方法,抽象方法,强制子类重写,非抽象方法,可以让子类继承下去用
    抽象类不能直接实例化,可以采用多态的方式,间接实例化
    抽象类的子类,要么重写父类中所有的抽象方法,要么自己也是一个抽象类。
    抽象类中有构造方法,用来子类初始化父类要用
    案例二:
public abstract class A {

    public abstract void a();

    public abstract void c();
}



public abstract class B extends A{

   public abstract void d();
}


public  class C extends B{

    @Override
    public void d() {

    }

    @Override
    public void a() {

    }

    @Override
    public void c() {

    }
}

注意:子类c要重写抽象类b和抽象类a中的所有抽象方法

案例三:

public abstract class Person {
    public String name;
    public int age;
    public abstract void eat();
    public abstract void sleep();
    public void playGame(){
        System.out.println("玩游戏");
    }

}


public class Teacher extends Person {
    @Override
    public void eat() {
        System.out.println("老师爱吃搅团");
    }

    @Override
    public void sleep() {
        System.out.println("老师经常失眠");
    }
}


public class Student extends Person{
    @Override
    public void eat() {
        System.out.println("学生爱吃烤串");
    }

    @Override
    public void sleep() {
        System.out.println("学生通宵不寐");
    }
    public void watchTV(){
        System.out.println("学生看电视");
    }
}


public class MyTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.name = "董永";
        p.age = 29;
        System.out.println(p.name + "====" + p.age);
        p.sleep();
        p.playGame();
        p.eat();
        ((Student) p).watchTV();
        System.out.println("------------------------");
        p = new Teacher();
        p.name = "沈某某";
        p.age = 20;
        System.out.println(p.name + "===" + p.age);
        p.eat();
        p.eat();
        p.playGame();
    }
}


案例四:
案例演示
假如我们在开发一个系统时需要对员工(Employee) 类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
经理(Manager) 也是员工,除了含有员工的属性外,另为还有一个奖金(bonus) 属性。
然后定义工作的方法.
请使用继承的思想设计出员工类和经理类。

public abstract class Person {
    //姓名、
    //
    //工号以及工资(salary)。
    public String name;
    public int num;
    public double salary;

    public abstract void work();

}


public class Employee extends Person{
    @Override
    public void work() {
        System.out.println("员工敲代码");
    }
}


public class Manager extends Person{
    public double bonus;

    @Override
    public void work() {
        System.out.println("经理管理员工");
    }
}

public class MyTest {
    public static void main(String[] args) {
       
        Person p = new Employee();
        p.name="张三";
        p.num=1;
        p.salary=2000;
        System.out.println(p.name+"=="+p.num+"==="+p.salary);
        p.work();
        System.out.println("--------------------");
        p=new Manager();
        p.name = "lisi";
        p.num = 2;
        p.salary = 4000;
        ((Manager) p).bonus=2000;
        System.out.println(p.name+"==="+((Manager) p).bonus+"==="+p.num);
        p.work();
    }
}


案例五:

public class MyTest {
    public static void main(String[] args) {
    }
}


abstract class A{
    int num=100;
    public static final int num2=1000;

    public A(int num) {
        this.num = num;
    }
    
}

抽象类面试题

 1.  抽象类中的成员变量 即可定义变量也可以定义常量
       抽象类中有构造方法,用来子类初始化化父类
   抽象类中既可以有抽象方法,也可以有非抽象方法
 2. 一个类如果没有抽象方法,可不可以定义为抽象类 ? 如果可以,有什么意义 ?
      可以 外界不能直接创建对象

  3.  abstract不能和哪些关键字共存 ?

      不能和private 共存 矛盾
      不能和 final 共存 矛盾
      不能和 static 共存 没有意义

接口

  • 概述
    继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
    但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
    而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。
    所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
    所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可

  • 接口特点
    a:接口用关键字interface表示 格式: interface 接口名 {}
    b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
    c:接口不能实例化
    那么,接口如何实例化呢?
    按照多态的方式来实例化。
    d:接口的子类
    a:可以是抽象类。但是意义不大。
    b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
    接口的成员特点

  • 接口的成员特点
    成员变量;只能是常量,并且是静态的。
    默认修饰符:public static final
    建议:自己手动给出。
    构造方法:接口没有构造方法。
    成员方法:只能是抽象方法。
    默认修饰符:public abstract
    建议:自己手动给出。

案例

案例一:

public abstract class Animal {

    public abstract void eat();
}


public interface CalcInterface {
    //用来定义额外功能
    public abstract void calc();

}


public class Cat extends Animal implements CalcInterface{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catcheMouse(){
        System.out.println("猫抓老鼠");
    }

    @Override
    public void calc() {
        System.out.println("猫经过不断的努力学习,会做算术了");
    }
}


public class Dog extends Animal implements CalcInterface{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("狗看门");
    }

    @Override
    public void calc() {
        System.out.println("狗经过自己的学习,也学会了做算术");
    }
}


public class MyTest {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Animal an = cat;
        an.eat();
        // CalcInterface 是猫的一个父接口,猫类也是父接口的一个子类
        CalcInterface calcInterface = cat;
        calcInterface.calc();
        //多态
        CalcInterface c = new Dog();
        c.calc();
        //接口不能new 对象

    }
}


案例二:

public class MyTest {
    public static void main(String[] args) {
        //接口中成员变量的特点
        //接口中的成员变量全是静态的公共常量
        //接口中没有构造方法的
        //接口中没有非抽象方法,全是抽象方法

        int a = A.A;
        System.out.println(a);
        int num = A.num;

    }
}

interface A{
    //接口中成员变量前面有默认的修饰符  public static final
    int num=100;
    public static final  int A=1000;

   //方法前面存在默认修饰符 public abstract
    public abstract void hehe();
    void test();
}

注意:
CalcInterface 是猫的一个父接口,猫类也是父接口的一个子类

类与类,类与接口,接口与接口的关
a:类与类:
继承关系,只能单继承,可以多层继承。
b:类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
c:接口与接口:
继承关系,可以单继承,也可以多继承。
案例三

public class MyTest {
    public static void main(String[] args) {
        //类跟类之间的关系
        // 类跟类是继承关系,只能是单继承,支持多层继承
        // 类跟接口是实现关系 既可以实现一个接口,也可以实现多个接口,实现接口,必须重写接口中所有的抽象方法
        // 接口跟接口的关系,继承关系,而且可以多继承
    }

}

class Fu{}
interface A{

    void a();
}
interface C{
    void c();
}

class B extends Fu implements A,C{


    @Override
    public void a() {

    }

    @Override
    public void c() {

    }
}

interface  E{
    void e();
}

interface F{
    void f();
    void ff();

}

interface G extends E,F{
    void g();
    void gg();

}

class V implements G{


    @Override
    public void e() {

    }

    @Override
    public void f() {

    }

    @Override
    public void ff() {

    }

    @Override
    public void g() {

    }

    @Override
    public void gg() {

    }
}

抽象类和接口的区别

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

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

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

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

案例四:

public class MyTest2 {
    //JDK1.8之后,接口中可以定义默认方法
    public static void main(String[] args) {
     C c= new C();
     A a=c;
     a.test();
     a.test2();
     a.test3();
     B b=c;
     b.test22();
     b.test333();


    }
}

interface A{
    void hehe();
    public default void test(){
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

    public default void test2() {
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

    public default void test3() {
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

}

interface B {
    void hehe();

    public default void show() {
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

    public default void test22() {
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

    public default void test333() {
        System.out.println("JDK1.8之后接口中,可以定义默认方法,可以有方法的具体实现");
    }

}

class C implements A,B{


    @Override
    public void hehe() {

    }

    @Override
    public void test22() {

    }
}

案例五

案例演示
//动物类:姓名,年龄,吃饭,睡觉。
//动物培训接口:跳高
//猫继承动物类
//狗继承动物类
// 部分猫继承猫类并实现跳高接口
//部分狗继承狗类并实现跳高接口
//
//通过抽象类测试基本功能。
//通过接口测试扩展功能。

public abstract class Animal {
    public String name;
    public int age;
    public abstract void eat();
    public abstract void sleep();
}


public interface JumpInterface {
    void jump();
}


public class Cat extends Animal{
    @Override
    public void eat() {

    }

    @Override
    public void sleep() {

    }
}


public class KittyCat extends Cat implements JumpInterface{
    @Override
    public void eat() {
        System.out.println("kitty猫吃蛋糕");
    }

    @Override
    public void sleep() {
        System.out.println("kitty猫整体睡觉");
    }

    @Override
    public void jump() {
        System.out.println("kitty猫学会跳高了");
    }
}


public class TomCat extends Cat{
    @Override
    public void eat() {
        System.out.println("汤姆猫想吃杰瑞");
    }

    @Override
    public void sleep() {
        System.out.println("汤姆猫假装睡觉");
    }

    public void actor(){
        System.out.println("汤姆猫是一个演员");
    }
}


public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}
public class WangCaiDog extends Dog implements JumpInterface{

    @Override
    public void eat() {
        System.out.println("旺财吃的是狗粮");
    }

    @Override
    public void sleep() {
        System.out.println("旺财晚上睡觉");
    }

    public void lookDoor(){
        System.out.println("旺财看门");
    }

    @Override
    public void jump() {
        System.out.println("旺财学会里跳高");
    }
}


public class XiaoTianDog extends Dog{
    @Override
    public void eat() {
        System.out.println("哮天犬吃的是天宫套餐");
    }

    @Override
    public void sleep() {
        System.out.println("哮天犬不睡觉");
    }

    public void fashu(){
        System.out.println("哮天犬会法术");
    }
}


public class MyTest {
    public static void main(String[] args) {
       
        KittyCat cat = new KittyCat();
        Animal an = cat;
        an.name = "kitty";
        an.age = 1;
        System.out.println(an.name + "===" + an.age);
        an.eat();
        an.sleep();
        JumpInterface jumpInterface = cat;
        jumpInterface.jump();

        System.out.println("---------------");
        TomCat tomCat = new TomCat();
        an = tomCat;
        an.name = "tom";
        an.age = 2;
        System.out.println(an.name + "===" + an.age);
        an.eat();
        an.sleep();
        System.out.println("----------------------------------");
        WangCaiDog wc = new WangCaiDog();
        an = wc;
        an.name = "旺财";
        an.age = 3;
        System.out.println(an.name + "===" + an.age);
        an.sleep();
        an.eat();
        //WangCaiDog w= (WangCaiDog) an;
        //w.lookDoor();
        ((WangCaiDog) an).lookDoor();
        jumpInterface = wc;
        jumpInterface.jump();

        System.out.println("-----------------");
        XiaoTianDog xiaoTianDog = new XiaoTianDog();
        an = xiaoTianDog;
        an.name = "哮天犬";
        an.age = 10000;
        an.eat();
        an.sleep();
        //向下转型
        ((XiaoTianDog) an).fashu();
    }
}


类和接口的传参和返回值

案例

案例一:

public class MyTest {
    public static void main(String[] args) {
        Student student = new Student();
        //如果你以后看到一个方法的形参要一个类 类型,你就传一个该类的对象
        int num=2;
        set(student,num);
        student.show(new Student(),100);
        System.out.println(student.num);//100

    }

    public static void set(Student student,int num){
        student.num=num;
    }
}

class Student{
    int num=10;

    public void show(Student student,int num){
        student.num=num;
    }

}


案例二:

public class MyTest {
    public static void main(String[] args) {
        int num=1;
        Zi zi = new Zi();
        //如果你以后看到一个方法的形参要一个抽象类 类型,那么你就传一个该抽象类的子类对象
        set(new Zi(),num);
        zi.show(188);
        System.out.println(zi.num); //
    }

    public static void set(Fu fu,int num){
        fu.num=num;
    }
}

abstract class Fu{
    int num=100;
    public abstract void show(int num);
}

class Zi extends Fu{
        int num=10;
    @Override
    public void show(int num) {
        this.num=num;
    }
}


案例三:

public class MyTest {
    public static void main(String[] args) {
        int num=1;
        //如果你以后看到一个方法的形参要一个接口类型,你要传一个该接口的子类对象
        B b = new B();
        set(b,num);
       // b.show(109);
        System.out.println(b.a);//10
        System.out.println(b.NUM); //100
        System.out.println(A.NUM); //100
        System.out.println(B.NUM); //100

    }
    public static void set(A a,int num){
       new B().a=num;
       a.show(num);

    }
}

interface A{
    public static final int NUM=100;
    void show(int num);
}

class B implements A{
        int a=10;

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


案例四:

public class MyTest {
    public static void main(String[] args) {
        int num = 100;
        A a = new A();
        A a1 = a.getA(num);
        System.out.println(a.num);// 1
        System.out.println(a1.num); // 1
        System.out.println(a);
        System.out.println(a1);
        System.out.println(a == a1);
    }

    public static A getAA(A a, int num) {
        a.num = num;
        return a;
    }
}

class A {
    int num = 1;

    //如果你以后看到一个方法的返回值类型 是一个 类 类型,你就返回该类的一个对象
    public A getA(int num) {
        A a = new A();
        a.num = num;
        //  return a;
        return this;
    }
}

案例五:

public class MyTest {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();

        int num=2;

        MyInterface myInterface = get(myClass, num);

        myClass.show(109);

        System.out.println(myClass.num); //

        System.out.println(myInterface.NUM);//

    }
    //如果你以后看到一个方法的返回值类型,要一个接口类型,你就返回该接口的一个子类对象
    public static MyInterface get(MyClass myClass,int num){
        myClass.num=num;
        return myClass;
    }

}

interface MyInterface{
    int NUM=100;
    void show(int num);
}

class MyClass implements MyInterface{
    int num=1;
    @Override
    public void show(int num) {
        this.num=num;
    }
}

案例六:

public class MyTest {
    public static void main(String[] args) {
        Zi zi = new Zi();
        Fu fu = zi.getFu(zi, 109);
        System.out.println(zi.num); //109
        System.out.println(fu.num); //109
        System.out.println(zi);
        System.out.println(fu);
    }
}

abstract class Fu {
    int num = 10;
}

class Zi extends Fu {
    //如果你以后看到一个方法的返回值类型,要一个抽象类 类型,你就返回一个该抽象类的子类对象
    public Fu getFu(Fu fu, int num) {
        fu.num = num;
        // return new Zi();
        return this;
    }
}


案例七:

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;
    }
}


注意链式编程

案例八:

public class Teacher {

    protected void show(){
        System.out.println("学生类里面的show方法");
    }

    public void hehe(){
        show();
    }
}


public class MyTest {
    public static void main(String[] args) {
        new Teacher().show();
    }
}

**注意:**不同包下的类访问调用需要导包,同一包下的类使用无需导包;

DAY10回顾

下面对DAY进行回顾

DAY11JAVASE基础知识

package

在这里插入图片描述

import

在这里插入图片描述

权限修饰符

在这里插入图片描述

内部类

在这里插入图片描述

匿名内部类

在这里插入图片描述

常用的API

常用api

object(类)

1.在这里插入图片描述
2.在这里插入图片描述
3.在这里插入图片描述
4.在这里插入图片描述
5.在这里插入图片描述
6.在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值