面向对象

面向对象


OOP的本质:以类的方式组织代码,以对象的防止组织(封装)数据

三大特性

  1. 封装

    • 保护数据、隐藏代码细节、属性私有set/get

    • alt+insert:自动生成get、set方法

  2. 继承

    • java类只有单继承,接口有多继承

    • final修饰后不能被继承

    • ctrl+h显示继承树

    • super

//父类
//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {

    protected String name = "wmj";

    public Person() {
        System.out.println("person的无参构造函数");
    }

    public void print() {
        System.out.println("person");
    }
}

//子类
class Student extends Person {

    private String name = "ww";

    public Student() {
        //隐藏代码 调用了父类的无参构造函数

        super();//调用父类的构造器必须放在第一行
        System.out.println("student的无参构造函数执行了");
    }

    public Student(String name) {
        this.name = name;
    }

    public void print() {
        System.out.println("student");
    }

    public void test(String name) {
        System.out.println(name);//hhh
        System.out.println(this.name);///ww
        System.out.println(super.name);//wmj
    }
}

//测试
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test("hhh");
    }
}
     /*
     person的无参构造函数
     student的无参构造函数执行了
     haha
     ww
     wmj
     */

方法重写(只和非静态方法有关)

  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大不可缩小:public>protected>default>private
  • 抛出的异常:范围,可以缩小不能扩大
  • 静态方法
class B {
    public static void test() {
        System.out.println("B.test()");
    }
}

class A extends B {
    public static void test() {
        System.out.println("A.test()");
    }
}

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

        //方法的调用只和左边的数据类型有关
        A a = new A();
        a.test();//A.test()

        //父类的引用指向了子类
        B b = new A();
        b.test();//B.test()
    }
}
  • 非静态方法
class B {
    public void test() {
        System.out.println("B.test()");
    }
}

class A extends B {
    @Override
    public void test() {
        System.out.println("A.test()");
    }
}

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

        //方法的调用只和左边的数据类型有关
        A a = new A();
        a.test();//A.test()

        //父类的引用指向了子类
        B b = new A();
        b.test();//A.test()
    }
}
  1. 多态
    • 同一方法可以根据发送对象的不同而采用多种不同的行为方式

    • 多态是方法的多态

    • 父类和子类有联系 类型转换异常:ClassCastException!

    • 存在条件:继承关系、方法要重写、父类引用指向子类对象!

    • static属于类,final在常量池,private方法都不能重写

//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {

    public void run() {
        System.out.println("person");
    }
}

class Student extends Person {
    @Override
    public void run() {
        System.out.println("student");
    }

    public void eat() {
        System.out.println("eat");
    }
}

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

        //一个对象的实际类型是确定的
        //可以指向的引用类型就不确定了  父类的引用指向子类

        //Student 能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //Person 不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();

        s1.run();//student 子类重写了父类的方法,执行子类的方法
        s2.run();//student

        //对象能执行那些方法,主要看左边的类型
        //s2.eat();错
        ((Student) s2).eat();
        s1.eat();
    }
}

instance

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

        //System.out.println(x instanceof y);能否编译通过取决于是否有父子关系
        //xy是同一级别会编译报错

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object1 = new Student();
        System.out.println(object1 instanceof Student);//true
        System.out.println(object1 instanceof Person);//true
        System.out.println(object1 instanceof Object);//true
        System.out.println(object1 instanceof Teacher);//false
        System.out.println(object1 instanceof String);//false

        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(object2 instanceof String);编译报错

        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);编译报错
        //System.out.println(student instanceof String);编译报错
    }
}
  • 父转子要强制转换,才能使用子类特有方法,丢失父类子自己的那个被子类重写的方法

  • 子转父,会丢失子类特有方法

//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {

    public void run() {
        System.out.println("person run");
    }
}

class Student extends Person {

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

    public void go() {
        System.out.println("go");
    }
}

public class Application {
    public static void main(String[] args) {
        //父转子
        Person student1 = new Student();
        //student1.go();父类不能调用子类独有的方法,转换成子类的类型才行
        ((Student) student1).go();//强制类型转换
        ((Student) student1).run();//strdent run 丢失父类子自己的那个被子类重写的方法

        //子转父
        Student student2 = new Student();
        student2.go();
        Person person = student2;
        //person.go();子类转父类丢失子类特有的方法
    }
}

static

class Student extends Person {

    //执行顺序
    //第2.赋初始值
    {
        System.out.println("匿名代码块");
    }

    //第1.只执行一次
    static {
        System.out.println("静态代代码块");
    }

    //第3.
    public Student() {
        System.out.println("构造函数");
    }

    //执行顺序
    //静态代代码块
    //匿名代码块
    //构造函数
}
   
// import static java.lang.Math.random;
// 静态导入包 Math.random -> random

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

        Student student = new Student();

    }
}

抽象类

public abstract class Action {

    //不能new出来,只能靠子类去继承

    //让子类去实现抽象方法,除非他的子类也是抽象类
    //抽象方法只能在抽象类里
    public abstract void doSomething();

    //可以写普通的方法
    public void fun() {
        System.out.println("ttt");
    }
}
  • 构造器

    抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生,可以在其内部实现子类必须执行的代码

接口

public interface UserService {

    //没有构造方法
    //常量都是public static final
    int AGE = 0;

    //接口中定义的方法都是抽象的public
    void add(); // public abstract

    void delete();

    void update();

    void query();
}

public interface TimeService {
    void timer();
}


//利用接口实现多继承
public class UserServiceImpl implements UserService, TimeService {

    //实现了接口的类必须重写接口中的所有方法
    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }

    @Override
    public void query() {

    }

    @Override
    public void add() {

    }

    @Override
    public void timer() {

    }
}

内部类

class Outer {
    private int id = 10;

    public void out() {
        System.out.println("外部类的方法");
    }

    // 成员内部类:依附外部类而存在
    // 在定义的内部类的构造器是无参构造器,编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用
    class Inner {
        public void in() {
            System.out.println("内部类的方法");
        }

        public void getID() {
            System.out.println(id);
        }

        // 局部内部类:定义在一个方法或者一个作用域里面的类,访问仅限于方法内或者该作用域内
        public void method() {
            class Inner2 {

            }
        }
    }

    // 静态内部类:不需要依赖于外部类,和类的静态成员属性类似,并且它不能使用外部类的非static成员变量或者方法
    static class Inner2 {

    }
}


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

        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();

        // 获得外部类的私有属性
        inner.getID();

        new Outer().out();

        // 匿名内部类,不用把实例保存到变量中
        new UserService() {
            @Override
            public void hello() {

            }
        };
    }
}

interface UserService {
    void hello();
}
posted @ 2021-03-13 13:29  n1ce2cv  阅读(30)  评论(0编辑  收藏  举报