Java学习day07

Java抽象类和抽象方法

为什么要用抽象类,当子类要继承中父类的成员方法时,如果子类就是不重写怎么办?或者说父类时一个人写的 子类又是另外一个人写的那个人不知道要重写那该怎么办?这里就可以运用抽象类来强制对方重写子类中的成员方法了

抽象方法:

将共性的行为(方法)抽到父类之后.由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体.该方法就定义为抽象方法

抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类.

抽象类和抽象方法的定义格式

抽象方法的定义格式:

public abstract 返回值类型 方法名(参数列表);

抽象类的定义格式:

public abstract class 类名{}

抽象类和抽象方法的注意事项

抽象类不能实例化

抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

可以有构造方法

抽象类的子类:要么重写抽象类中的所有抽象方法 要么是抽象类

Person类:

public abstract  class Person {
    private String name;
    private int age;
    //抽象类中的构造方法的作用:当创建子类的时候,给属性赋值.

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    
    public abstract void work();
}

学生类:

public class Student extends Person{
    public Student(){}
    public Student(String name,int age){
        super(name,age);
    }
    @Override
    public void work(){
        System.out.println("学生的工作是学习");
    }
}

老师类:

public abstract class Teacher extends Person{
    
    
}

编写带有抽象类的标准Javabean类

青蛙frog   属性:名字,年龄   行为:吃虫子,喝水

狗Dog      属性:名字,年龄    行为:吃骨头,喝水

山羊Sheep  属性:名字,年龄   行为:吃草,喝水

这里的吃就可以设计成一个抽象方法

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    public void drink(){
        System.out.println("动物在喝水");
    }
    public abstract void eat();
}
public class Dog extends Animal{
    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println("狗吃骨头");
    }
}
public class Frog extends Animal{
    public Frog() {
    }

    public Frog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println("青蛙在吃虫子");
    }
}
public class Sheep extends Animal{
    public Sheep() {
    }

    public Sheep(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println("山羊在吃草");
    }
}

 

 接口

为什么有接口?

 

 

 

 Animal类:

public abstract class Animal {
    private int age;
    private String name;

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Animal(){

    }
    public abstract void eat();
}

Dog类: 

public class Dog extends Animal implements swim{
    public Dog(int age, String name) {
        super(age, name);
    }

    public Dog() {
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void swim() {
        System.out.println("狗刨");
    }
}

Rabbit类:

public class Rabbit extends Animal{

    public Rabbit(int age, String name) {
        super(age, name);
    }

    public Rabbit() {
    }

    @Override
    public void eat() {
        System.out.println("兔子在吃胡萝卜");
    }
}

Frog类:

public class Frog extends Animal implements swim{
    public Frog(int age, String name) {
        super(age, name);
    }

    public Frog() {
    }

    @Override
    public void eat() {
        System.out.println("青蛙在吃虫子");
    }

    @Override
    public void swim() {
        System.out.println("青蛙在蛙泳");
    }
}

游泳接口:

public interface swim {
    public abstract void swim();
}

Test类:

public class Test {
    public static void main(String[] args) {
        //创建对象
        Frog f =new Frog(1,"yjy");
        System.out.println(f.getName()+", "+f.getAge());

        f.eat();
        f.swim();

        Rabbit r =new Rabbit(2,"bb");
        System.out.println(r.getName()+", "+r.getAge());
        r.eat();
    }
}

接口中成员的特点:

成员变量:只能是常量  默认修饰符:public static final 

构造方法:没有

成员方法:只能是抽象方法  默认修饰符:public abstract 

JDK7以前:接口中只能定义抽象方法

接口和类之间的关系

类和类的关系

继承关系,只能单继承,不能多继承,但是可以多层继承

类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

接口1:

public interface Inter1 {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
}

接口2:

public interface Inter2 {
    public abstract void method4();
    public abstract void method5();
    public abstract void method6();
}

类:

public class InterImpl implements Inter1,Inter2{
//如果有重名的方法 只需要重写一次就行了
    @Override
    public void method1() {
        System.out.println("method1");
    }

    @Override
    public void method2() {
        System.out.println("method2");
    }

    @Override
    public void method3() {
        System.out.println("method3");
    }

    @Override
    public void method4() {
        System.out.println("method4");
    }

    @Override
    public void method5() {
        System.out.println("method5");
    }

    @Override
    public void method6() {
        System.out.println("method6");
    }
}

接口和接口的关系

继承关系,可以单继承,也可以多继承

细节:如果实现类实现了最下面的子接口,那么就需要重写所有的抽象方法

public interface Inter1 {
    public abstract void method1();
}
public interface Inter2 {
    public abstract void method2();
}
public interface Inter3 extends Inter1,Inter2{
    public abstract void method3();
}
public class InterImpl implements Inter3{

    @Override
    public void method1() {

    }

    @Override
    public void method2() {

    }

    @Override
    public void method3() {

    }
}

//因为现在不行让外界去直接创建人的对象
//因为直接创建顶层人的对象是没有意义的
//所以就把他写为抽象的
public abstract class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = 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;
    }


}
public abstract class Coach extends Person{
    public Coach() {
    }

    public Coach(String name, int age) {
        super(name, age);
    }

    public abstract void teach();
}
public abstract class Sporter extends Person{
    public Sporter() {
    }

    public Sporter(String name, int age) {
        super(name, age);
    }

    public abstract void study();//为什么要写成抽象的 因为乒乓球和打篮球学的东西不一样


}
public class PingPongSporter extends Sporter implements English{
    public PingPongSporter() {
    }

    public PingPongSporter(String name, int age) {
        super(name, age);
    }

    @Override
    public void speakEnglish() {
        System.out.println("乒乓球运动员在说英语");
    }

    @Override
    public void study() {
        System.out.println("乒乓球运动员在学习如何打乒乓球");
    }
}
public class PingPongCoach extends Coach implements English{
    public PingPongCoach() {
    }

    public PingPongCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("乒乓球教练正在教如何打乒乓球");
    }

    @Override
    public void speakEnglish() {
        System.out.println("乒乓球教练在说英语");
    }
}
public class BasketballSporter extends Sporter {
    public BasketballSporter() {
    }

    public BasketballSporter(String name, int age) {
        super(name, age);
    }

    @Override
    public void study() {
        System.out.println("篮球运动员在学习如何打篮球");
    }
}
public class BasketballCoach extends Coach{
    public BasketballCoach() {
    }

    public BasketballCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("篮球教练正在教如何打篮球");
    }
}
public class Test {
    public static void main(String[] args) {
        PingPongSporter pps=new PingPongSporter("刘siwen",23);
        System.out.println(pps.getName()+", "+pps.getAge());
        pps.study();
        pps.speakEnglish();
    }
}

多学三招:

1.JDK8开始接口中新增的方法

2.接口的应用

3.适配器设计模式

JDK8开始接口中新增的方法

JDK以前:接口中只能定义抽象方法

JDK8的新特性:接口中可以定义有方法体的方法.(默认,静态)

JDK9的新特性:接口中可以定义私有方法.

 

 

 

 

public interface InterA {
    public abstract void method();
    public default void show(){
        System.out.println("InterA接口中的默认方法 ---show");
    }
}
public interface InterB {
    public default void show(){
        System.out.println("InterB接口中的默认方法 ---show");
    }
}
public class InterImpl implements InterA ,InterB{

    @Override
    public void method() {
        System.out.println("实现类重写的抽象方法");
    }

    @Override
    public void show() {
        System.out.println("重写接口中的默认方法");
    }
}
public class Test {
    public static void main(String[] args) {
        InterImpl ii =new InterImpl();
        ii.method();
        ii.show();
    }
}

public interface InterA {
    public static void show(){
        System.out.println("Inter接口中的静态方法");
    }
    public abstract void method();

}
public class InterImpl implements InterA {

    @Override
    public void method() {
        System.out.println("实现类重写的抽象方法");
    }

    //这个不叫重写
    public static void show(){
        System.out.println("实现类的静态方法");
    }
}
public class Test {
    public static void main(String[] args) {
        //调用接口中的静态方法
        InterA.show();
        //调用实现类的静态方法
        InterImpl.show();

        //子类把父类继承下来的虚方法表里面的方法进行了覆盖了,这才叫重写.
    }
}

public interface InterA {
//    public default void show1(){
//        System.out.println("show1方法开始执行了");
//       show3();
//    }
//    public default void show2(){
//        System.out.println("show2方法开始执行了");
//        show3();
//    }
    public default void show1(){
        System.out.println("show1方法开始执行了");
        show4();
    }
    public default void show2(){
        System.out.println("show2方法开始执行了");
        show4();
    }
    //普通的私有方法,给默认方法服务的
    private void show3(){
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
    }
    //静态的私有方法,给静态方法服务的
    private void show4(){
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
    }
}

接口的应用

 

 

public interface InterA {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
    public abstract void method4();
    public abstract void method5();
    public abstract void method6();
    public abstract void method7();
    public abstract void method8();
    public abstract void method8();
    public abstract void method10();
    //在这10个抽象函数中我只想使用第五个
}
public abstract class InterAdapter implements InterA{
    //这里加上abstract是为了防止外界创建它的对象


    @Override
    public void method1() {

    }

    @Override
    public void method2() {

    }

    @Override
    public void method3() {

    }

    @Override
    public void method4() {

    }

    @Override
    public void method5() {

    }

    @Override
    public void method6() {

    }

    @Override
    public void method7() {

    }

    @Override
    public void method8() {

    }

    @Override
    public void method10() {

    }
}
public class InterImpl extends InterAdapter{
    //我需要用到那个方法就重写那个方法就可以了


    @Override
    public void method5() {
        System.out.println("只要用第五个method");
    }
}

内部类

什么是内部类:

类的五大成员:属性,方法,构造方法,代码块,内部类

在一个类的里面,再定义一个类

举例:在A类的内部再定义B类,B类就被称为内部类

 

内部类的分类 

成员内部类

静态内部类

局部内部类

匿名内部类

前三种了解即可最后一个重点掌握

public class Test {
    public static void main(String[] args) {
        //创建对象的方式:
        //类名 对象名 = new 类名();
        //Student s =new Student();

        //内部类对象
        //Outer.Inner oi =new Outer().new Inner(); 如果修饰符权限为public

        //如果修饰符权限是private
        Outer o =new Outer();
        //1.Object inner = o.getInstance();
        System.out.println(o.getInstance());

    }
}
public class Outer {
    private class Inner{

    }
    public Inner getInstance(){
        return new Inner();
    }
}

 ???写什么好

public class Test {
    public static void main(String[] args) {
        Outer.inner oi = new Outer().new inner();
        oi.method();
    }
}

class Outer {	// 外部类
    private int a = 30;

    // 在成员位置定义一个类
    class inner {
        private int a = 20;

        public void method() {
            int a = 10;
            System.out.println(???);	// 10   答案:a
            System.out.println(???);	// 20	答案:this.a
            System.out.println(???);	// 30	答案:Outer.this.a
        }
    }
}

 

 

 

匿名内部类

匿名内部类本质上就是隐藏了名字的内部类.

public class Test {
    public static void main(String[] args) {
        //整体我们可以理解为Swim接口的实现类对象
        //接口多态
        Swim s =new Swim(){
            @Override
            public void swim(){
                System.out.println("重写之后游泳方法");
            }
        };
        //编译看坐边,运行看右边
        
        s.swim();
        new Swim(){
            @Override
            public void swim(){
                System.out.println("重写之后游泳方法");
            }
        }.swim();
    }
}

匿名内部类真的没有名字吗?

只是不需要我们自己写而已Java已经写了 外部类类名+$+序号

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值