JAVA学习---抽象类,接口

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/qq_37757008/article/details/81408567 https://blog.csdn.net/qq_37757008/article/details/83092334

周日我们进一步学习了抽象类,接口,还好好分析了四种权限修饰符的特性。
在这里插入图片描述
以上是复习上周的面向对象的内容。

抽象类

  • 定义
    我们先从一个例子引出抽象类的定义:比如我说一只动物,你知道我说的是什么具体动物吗?只有看到了具体的动物,你才知道,这是什么动物。 所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。所以,在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。父类当中不给出所有子类共性功能的实现,强制子类根据各自的差异性去重写
  • 抽象类的特点
    1.抽象类和抽象方法必须用abstract关键字修饰

抽象类:abstract class 类名{}
抽象方法:public abstract void 方法名();
//抽象方法:只给出方法声明,不给出方法的具体实现

2.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。可是抽象类中的构造方法不能进行实例化,因此它没有意义。
3.抽象类不能直接实例化,而是需要按照多态的方式,由具体的子类实例化,即抽象类多态。
4.如果一个类中如果有了抽象方法,则此类必须为抽象类。
5.抽象类的子类要门时抽象类,要么 必须重写抽象类中的所有抽象方法。所以说抽象类的成员方法是强制要求子类做的事情。

//定义抽象类Animal写了两个抽象方法eat(),sleep();
public abstract class Animal {

    public abstract void eat();
    public abstract void sleep();
}
//定义子类Cat继承抽象类Animal
public class Cat extends Animal{
    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override			//重写父抽象类中的所有方法。
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫经常睡觉");
    }
    public void catcheMouser(){				//定义了一个Cat独有的方法
        System.out.println("猫抓老鼠");
    }
}
//定义子类Dog继承抽象类Animal
public class Dog extends Animal{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override				////重写父抽象类中的所有方法。
    public void eat() {
        System.out.println("够吃骨头");
    }
    @Override
    public void sleep() {
        System.out.println("狗晚上睡觉");
    }
    public void lookDoor(){				//定义了一个Dog独有的方法
        System.out.println("狗看门");
    }
}
//定义测试类test
public class Test4 {
    public static void main(String[] args) {
        Animal an = new Dog();    				//多态
        an.sleep();
        an.eat();
        Dog dog = (Dog) an;					//向下转型
        dog.setName("旺财");
        dog.setAge(5);
        System.out.println(dog.getName());
        System.out.println(dog.getAge());
        dog.lookDoor();
        System.out.println("-----------------------");
        an = new Cat();
        an.eat();
        an.sleep();
        Cat cat = (Cat) an;				//向下转型
        cat.setName("小白");
        cat.setAge(2);
        cat.catcheMouser();
        System.out.println(cat.getAge());
        System.out.println(cat.getName());   
    }
}

在这里插入图片描述
以上的例子充分展示了抽象类以及多态的使用方法。子类继承抽象父类,并且重写父类中的所有方法,同时定义了自身特有的方法,并通过多态向下转型调用使用。

注意抽象类关键字abstract和一些关键字是冲突的。
a. private 冲突(abstract定义抽象类,它强制要求子类重写方法,而private有将它私有,不许继承和重写,因此冲突)。
b. final 冲突(与private相似)
c. static 不能共存,这样无意义(static 修饰的方法算不上重写)

上面我们讨论了一些修饰符的特点,那我们就来详细讨论一下修饰符:
四种权限修饰符:private(私有) ,默认,protected(受保护的),public(公共的)

  • 权限表
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protect Y Y Y
public Y Y Y Y

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


接口

  • 概述
    我们继续之前的案例,猫狗除了吃饭睡觉(继承)我们想想狗一般就是看门,猫一般就是作为宠物了(多态,重写)。但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
    所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
    接口:定义一些扩展功能或者规范.哪个类想要具备这些扩展功能可以实现这个接口。
  • 定义
    关键字:interface
    格式:interface 接口名{}
    实现:implements class 类名 implements 接口名{}
  • 特点
    1.接口中的成员变量前面有默认修饰符 public static final 。
    2.方法前面默认有修饰符 public abstract 你可以省略不写,建议你写出来
    3.接口中所有的方法都是抽象方法,抽象类中可以有抽象,也可以有非抽象方法
    4.接口中没有构造方法
    5.接口中所有的成员变量都是公共的静态常量
    6.接口的子类可以是抽象类
    7.接口跟接口之间可以继承,而且是多继承
    8.接口不能创建对象,即接口不能实例化,如果想实例化要按照多态的方式来实例化。
    9.接口可以实现多继承,而default关键字可以允许在接口中定义默认类,这也相当于变相承认java多继承。

接口实例:

//定义抽象父类Animal
public abstract class Animal {
    public abstract void eat();
    public  abstract void sleep();
}
//定义接口MyInterface
public interface MyInterface {
    int NUM = 100;
    (public static final)  double D = 100;  //括号里的可以没有,默认修饰符。
    (public abstract) void fire();
    void hehe();

}
//implements 实现 用来实现一个接口的
//定义子类Dog,继承抽象父类Animal,同时调用接口MyInterface
public class Dog extends Animal implements MyInterface{
	//先重写抽象父类中的方法eat(),sleep().
    @Override
    public void eat() {
    }
    @Override        
    public void sleep() {
    }
    //实例化接口的方法fire(),jump().
    @Override
    public void fire() {      
        System.out.println("狗钻火圈了");
    }
    @Override
    public void jump() {
        System.out.println("狗跳高了");
    }
}
//test测试类
public class Test {
    public static void main(String[] args) {
        //接口不能实例化
        MyInterface my = new Dog(); //多态的形式
        my.fire();
        my.jump();
    }
}

在这里插入图片描述


  • !参数传递
    下面我们来说说java中的参数传递。
    1.如果一个方法的形参要一个 类型,则传一个该类的对象。
    2.如果一个方法的形参要一个 抽象类类型 那么你就传该类的一个子类对象 。
    3.如果一个方法的返回值类型要一个 接口 类型 你就返回一个该接口的子类对象。
    4.如果一个方法的返回值类型 要一个 类型,你就返回一个该类的对象。
    这里参数的传递给了我们一个很好的编程方法,链式编程(连调),这样可以简化编程的复杂性,但是需要我们对参数的传递有深刻的理解。

  • 内部类
    1.定义:
    将一个类 定义到另一个类的内部,我们就称之为内部类;将类A 定义到B类当中 我们称A为内部类,B 我们可以叫外部类;同时根据定义位置的不同,我们分为成员内部类,局部内部类;
    成员内部类:内部类在外部类的成员位置。
    局部内部类:内部类在外部类的局部位置(方法中)。
    2.内部类的特点:
    (1):内部类可以直接访问外部类的成员,包括私有的;
    (2):内部类被private 修饰后,外界不能创建内部类对象;
    (3):static 可以修饰内部类,同时静态内部类只能访问外部类的静态成员;
    (4):局部内部类访问局部变量必须用final修饰 在JDK1 .8之后默认就加上了;
    因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
    为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。

public class Outer {
    int num=100;
    private String name="abc";
    public void waiMethod(){
        //定义局部内部类
        //内部类可以直接访问外部类的成员 包括私有的
        class Inner{
            int nei=10;
            public void neiShow(){
                System.out.println(num);
                System.out.println(name);
            }
            public void neiTest(){
                waiTest();
            }
        }
        Inner inner = new Inner();
        System.out.println(inner.nei);
        inner.neiShow();
        inner.neiTest();
    }
    private void waiTest(){
        System.out.println("我是外部类的私有方法");
    }
}
public class Test5 {
    public static void main(String[] args) {
        //局部内部类,外界无法直接创建其对象
        new Outer().waiMethod();
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37757008/article/details/83092334