java-面向对象进阶

面向对象进阶

多态

同类型对象,表现出的不同形态

表现形式

父类类型 对象名称 = 子类对象;

前提

*有继承/实现关系

*有父类引用指向子类对象

*有方法重写

好处

使用父类作为参数,可以接受所有子类对象

多态调用成员的特点:

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

        Animal a = new Dog();
        //调用成员变量:编译看左边,运行也看左边
        //编译看左边:javac编译的时候,会看左边的父类中有没有这个变量,如果有编译成功,如果没有,编译失败
        //运行也看左边:运行时,实际获取的是左边父类中的成员变量
        System.out.println(a.name);//动物

        //调用成员方法
        //编译看左边:同上
        //运行看右边:运行的子类的方法
        a.show();//执行子类的方法“D 方法”
        
        a.eat();//会报错

    }
}
class Animal{
    String name = "动物";
    public void show(){
        System.out.println("A 方法");
    }
}

class Dog extends Animal{
    String name ="小狗";

    @Override
    public void show() {
        System.out.println("D 方法");

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

    }
}

多态的弊端:

不能调用子类的特有方法

如:上面代码中调用a.eat则会报错

解决方法:变回子类类型

if(a instanceof Dog){
            Dog d  =(Dog)a;
        }else {
            System.out.println("没有这个类型");
        }

此时可以调用

注:不能转化为其他类型,否则会报错

最好使用instanceof关键字进行判断

包:

作用:就是文件夹,来管理各种不同功能的java类

全类名:包名+类名

何时导包:

*使用同一个包中的类时,不需要导包

*使用java.lang包在的类时,不需要

*其他情况下都需要

*如果同时使用两个包中的同类名,需要用全类名

final

修饰方法: 表示该方法是最终方法,不能被重写

修饰类: 表明该类是最终类,不能被继承

修饰变量: 叫做常量,只能被赋值一次

常量的命名规范

单个单词:全部大写

多个单词:全部大写,单词之间用下划线隔开

注:如果修饰的变量是引用类型,地址值不变,对象内部可以改变

代码块

局部代码块:提前结束变量的声明周期

构造代码块:抽取构造方法中的重复代码

静态代码块:

格式:staticc{}

特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次

使用场景:在类加载的时候,做一些数据初始化的时候使用

抽象类

作用:抽取共性时,无法确定方法体,就把方法定义为抽象的

强制让子类按照某种格式重写(必须按照父类格式重写)

格式:

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

抽象类 public abstract class 类名{}

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

●抽象类不能实例化

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

●可以有构造方法

继承抽象类时:

*要么重写抽象类中的所有抽象方法

*要么是抽象类

接口

创建

java-面向对象进阶_第1张图片

public interface 接口名{}

*接口和类之间是实现关系,通过implements关键字表示

可以单实现,也可以多实现

public class 类名 implements 接口名1,接口名2{}

也可以在继承一个类的同时实现多个接口

public class 类名 implements 接口名1,接口名2{}

*接口的子类(实现类)

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

要么是抽象类

注:如果多实现时有重名的方法,重写时相当于将两个方法都重写

接口中成员的特点

*成员变量

只能是常量

默认修饰符:public static final

*构造方法 没有

*成员方法

只能是抽象方法

修饰默认符:public abstract

接口和类的关系

*类和类的关系

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

*类和接口的关系

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

*接口和接口的关系

继承关系,可以单继承和多继承(多继承时如果继承最子接口 需要全部重写方法)

JDK8以后接口中新增的方法

默认方法

*允许接口中定义默认方法,用关键词default修饰

作用:解决接口升级的问题

默认方法的定义格式:public default 返回值类型 方法名 (参数列表){}

package practice;

public interface Inter {
    public default void show(){
        System.out.println("默认方法");
    }
}
//默认方法必须写方法体 

注意事项

*默认方法不是抽象方法,不强制重写 如果重写要去掉default关键字

*public可以省略,default不可以省略

*如果实现了多个接口,其中有相同名字的默认方法,子类就必须重写

静态方法

格式:public static 返回值类型 方法名 (参数列表){}

public static void show (){
        System.out.println("静态方法");
    }

注意事项:

只能通过接口名调用,不能类名和对象名调用

public可以省略,static不可以省略

JDK9新增的方法

    public static void show1 (){
        System.out.println("show1方法");
        show4();
    }

    public static void show2(){
        System.out.println("show2方法");
        show4();
    }

    //普通的私有方法,给默认方法服务
    static void show3(){
        System.out.println("记录程序运行的一些细节");
    }

    //静态的私有方法,给静态方法服务的
    private static void show4(){
        System.out.println("记录程序运行的一些细节");
    }
}

适配器

当一个接口中抽象方法过多,但是我只要使用其中一部分的时候(类似于一个中间变量 temp)

书写步骤:

编写中间类XXXAdapet 实现对应的接口

对接口中的抽象方法进行空实现(方法体空着 不写)

让真正的实现类继承中间类,并重写需要的方法

为了避免其他类创建适配类的对象,中间的适配类要用abstarct进行修饰

如果实现类有其他父类,可以让适配类去继承

内部类

写在一个类里面的类就叫内部类

用处:

B类表示的事物是A类的一部分,且B单独存在没有意义

如:汽车的发动机,ArrayList的迭代器,人的心脏

访问特点:

内部类可以直接访问外部类的成员,包括私有

外部类要访问内部类的成员,必须先创建对象

成员内部类

写在成员位置的,属于外部类的成员

获取方法:

  1. 当成员内部类被private修饰时

在外部编写方法,对外提供内部对象

  1. 非私有修饰时,直接创建对象

  1. 当重名时

public class test1 {
    public static void main(String[] args) {
        //创建内部类的对象,并调用show方法
        Outer.Inner oi = new Outer().new Inner();

        oi.show();
    }
}
class Outer{
    private int a = 10;

    class Inner{
        private int a =20;

        public void show(){
            int a =30;
            //outer.this 获取了外部类对象的地址值
            System.out.println(Outer.this.a);//10
            System.out.println(this.a);//20
            System.out.println(a);//30
        }
    }
}

静态内部类

创建静态内部类的格式:

外部类名.内部类名 对象名 = new 外部类名.内部类名();

调用静态方法的格式:

外部类名.内部类名.方法名();

只要是静态的东西,都可以用类名点直接获取

public class test1 {
    public static void main(String[] args) {
        //创建静态内部类的对象
        Outer.Inner oi = new Outer.Inner();

        //调用非静态,先创建对象
        oi.show1();

        //直接用类名调用静态
        Outer.Inner.show2();
    }
}
 class Outer{

    static class Inner{
=
        public void show1(){
            System.out.println("非静态方法");
        }

        public static void show2(){
            System.out.println("静态方法");
        }
    }
}

匿名内部类

隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置

格式:

new 类/接口(){

重写的方法

};

包含继承或实现,方法重写,创建对象

整体就是一个类的子类对象或者接口的实现类对象

使用场景:

当方法的参数时接口或者类时,可以传递这个类

如果实现类只使用一次,就可以用匿名内部类简化代码

你可能感兴趣的:(java,开发语言,面试)