Java之面向对象编程

01、什么是面向对象

面向过程思想

  • 步骤清晰简单,第一步做什么,第二步做什么。。。
  • 面对过程适合处理一些较为简单的问题

面向对象思想

  • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思考。
  • 面向对象核实处理复杂的问题,适合处理需要多人协作的问题。

对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

什么是面向对象

oop(object-oriented programming)

面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据

三大特性

  • 封装
  • 继承
  • 多态

从认识论角度考虑是先有对象后有类,对象,是具体的事物。类,是抽象的,是对对象的抽象。

从代码运行角度考虑是先有类后有对象。类是对象的模板。

02、回顾方法的定义

03、回顾方法的调用

04、类与对象的创建

类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。

对象是抽象概念的具体实例。

05、构造器详解

一旦定义了有参构造,无参构造必须显示定义,否则无参构造无效。

06、创建对象内存分析

创建对象包含两个过程:

  1. 类构造器完成类初始化(分配内存、赋予默认值)
  2. 类实例化(赋予给定值)

父类

public class FartherClass {
    //静态变量
    public static String static_str = "父类--静态变量";
    //普通变量
    public String str = "父类--普通变量";
    //静态代码块
    static {
        System.out.println(static_str);
        System.out.println("父类--静态代码块");
        System.out.println();
    }
    //普通代码块
    {
        System.out.println(str);
        System.out.println("父类--普通代码块");
        System.out.println();

    }
    //构造器
    FartherClass() {
        System.out.println("父类--构造器");
        System.out.println();
    }

}

子类

public class SonClass extends FartherClass{
    //静态变量
    public static String son_static_str = "子类--静态变量";
    //普通变量
    public String son_str = "子类--普通变量";
    //静态代码块
    static {
        System.out.println(son_static_str);
        System.out.println("子类--静态代码块");
        System.out.println();
    }
    //普通代码块
    {
        System.out.println(son_str);
        System.out.println("子类--普通代码块");
        System.out.println();
    }
    //构造器
    SonClass() {
        System.out.println("子类--构造器");
        System.out.println();
    }

    public static void main(String[] args) {
        System.out.println("子类--Main");
        System.out.println();
        new SonClass();
    }
}

输出

父类--静态变量
父类--静态代码块

子类--静态变量
子类--静态代码块

子类--Main

父类--普通变量
父类--普通代码块

父类--构造器

子类--普通变量
子类--普通代码块

子类--构造器

img

分析

public class Person {
    public int age;
    public String name;

    public void walk() {
        System.out.println("正在走路。。。");
    }

}
public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.age = 18;
        person.name = "zyy";
        person.walk();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V2myeTrq-1647702927551)(C:/Users/ZHAYUYAO/AppData/Roaming/Typora/typora-user-images/image-20210508114057817.png)]

07、简单小结类与对象

类的生命周期

img

对象是通过引用来操作的

08、封装详解

该露的露,该藏的藏

程序设计要求:高内聚,低耦合

高内聚就是内部的数据操作细节自己完成,不允许外部干涉;

低耦合,仅暴露少量的方法给外部使用。

get/set

09、什么是继承

在java中,所有的类,都默认直接或者间接继承Object

idea快捷键:ctrl+h 打开继承关系

10、Super详解

super注意点

  • super是调用父类的构造方法,必须在构造方法的第一个
  • super必须只能出现在子类的方法或者构造方法中
  • super和this不能同时调用构造方法

this() 调用本类的构造方法

super() 调用父类的构造方法

11、方法重写

12、什么是多态

父类的引用指向子类的对象

父类

public class A {

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

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

    /**
     * 父类的特有类
     */
    public void say() {
        System.out.println("A say");
    }
}

子类

public class B extends A {
    //@Override 静态方法不能被重写
    public static void test() {
        System.out.println("B test");
    }

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

    /**
     * 子类特有类
     */
    public void hello() {
        System.out.println("B hello");
    }
}

测试类

public class Application {
    public static void main(String[] args) {
        B b = new B();
        b.test();
        b.print();
        b.hello();
        b.say();

        A a = new B();
        a.test();
        a.print();
        //父类引用指向子类的时候,下面这个调用不调用,能调用的方法看左边()父类
        //a.hello();
        a.say();
    }
}

输出

B test
B print
B hello
A say
A test
B print
A say

13、instanceof和类型转换

判断一个对象是什么类型

x instanceof y

x和y没有继承关系的话,是不能使用instanceof的,编译会报错!

public static void main(String[] args) {
    Person person = new Person();
    System.out.println(person instanceof Person);
    System.out.println(person instanceof Object);
    System.out.println(person instanceof Student);
    System.out.println(person instanceof Teacher);
    System.out.println("============");
    /**
         * true
         * true
         * false
         * false
         */
    Student student = new Student();
    System.out.println(student instanceof Person);
    System.out.println(student instanceof Object);
    System.out.println(student instanceof Student);
    //下面编译报错,因为没有继承关系
    //        System.out.println(student instanceof Teacher);
    System.out.println("============");
    /**
         * true
         * true
         * true
         */
    Person student01 = new Student();
    System.out.println(student01 instanceof Person);
    System.out.println(student01 instanceof Object);
    System.out.println(student01 instanceof Student);
    System.out.println(student01 instanceof Teacher);
    System.out.println("============");
    /**
         * true
         * true
         * true
         * false
         */
    Person teacher = new Teacher();
    System.out.println(teacher instanceof Person);
    System.out.println(teacher instanceof Object);
    System.out.println(teacher instanceof Student);
    System.out.println(teacher instanceof Teacher);
    /**
         * true
         * true
         * false
         * true
         */
}

14、static关键字详解

匿名代码块

静态代码块

public class Student {
    static {
        //只执行一次
        System.out.println("静态代码块");
    }
    {
        System.out.println("匿名代码块");
    }
    public Student() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        new Student();
        System.out.println("===========");
        new Student();
    }
}

输出

静态代码块
匿名代码块
构造方法
===========
匿名代码块
构造方法

静态导入包

//静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;

public class Test {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

15、抽象类

抽象类

  • 不能new这个抽象类,只能靠子类去实现它。约束
  • 抽象类中可以写普通方法
  • 抽象方法必须在抽象类中

抽象类存在构造器么?

–存在

16、接口的定义与实现

约束和实现分离

可以实现多个接口!

抽象思维!

接口不能被实例化,接口没有构造方法

17、N中内部类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类
public class Outer {
    private int outId = 1;
    public void outerMethod() {
        System.out.println("这是一个外部方法");
    }
    public void method() {
        class Innner3 {
            public void in() {
                System.out.println("Innner3.in");
            }
        }
    }

    /**
     * 静态内部类
     */
    public static class StaticInner {
        private int inId = 2;
        public void inMethod() {
            System.out.println("这是一个内部方法");
        }
        public static void staticInMethod() {
            System.out.println("这是一个内部方法");
        }
    }

    /**
     * 成员内部类
     */
    public class Inner {
        private int inId = 2;
        public void inMethod() {
            System.out.println("这是一个内部方法");
        }
        public void getOutId() {
            System.out.println("获取外部Id:"+outId);
        }
    }
}

class Inner2 {
}

interface Test {
    void print();
}

image-20210225115004603

测试类

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerMethod();
        Outer.Inner inner = outer.new Inner();
        inner.inMethod();
        inner.getOutId();
        System.out.println("=========");
        Outer.StaticInner staticInner = new Outer.StaticInner();
        staticInner.inMethod();
        Outer.StaticInner.staticInMethod();
        Test test = new Test() {
            @Override
            public void print() {
                System.out.println("匿名内部类");
            }
        };
        test.print();
    }
}
public static void main(String[] args) {
    //方法一(局部内部类)
    class Mouse implements USB {
        @Override
        public void service() {
            System.out.println("鼠标接入");
        }
    }
    USB mouse = new Mouse();
    mouse.service();
    //方法二(匿名内部类,可以减少代码量)
    USB usb = new USB() {
        @Override
        public void service() {
            System.out.println("鼠标接入");
        }
    };
    usb.service();
}

拓展

/**
 * 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】
 * 备注:从java8+开始,只要局部变量实际不变,那么final关键字可以忽略
 *
 * 原因:
 * 1. new出来的对象在堆内存中
 * 2. 局部变量是跟着方法走的,在栈内存当中
 * 3. 方法运行结束之后,立刻出栈,局部变量会立刻消失
 * 4. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失
 *
 */
//外部类
public class MyOuter {
    //方法
    public void outerMethod() {
        //所在方法的局部变量
        int i = 10;
        i++;

        int finalI = i;
        //局部内部类
        class MyInner {
            public void innerMethod() {
                System.out.println(finalI);
            }
        }
    }
}

编译后生成MyOuter.class MyOuter$1MyInner.class

public class MyOuter {
    public MyOuter() {
    }

    public void outerMethod() {
        byte var1 = 10;
        int var3 = var1 + 1;

        class MyInner {
            MyInner(int var2) {
                this.val$finalI = var2;
            }

            public void innerMethod() {
                System.out.println(this.val$finalI);
            }
        }

    }
}
class MyOuter$1MyInner {
    MyOuter$1MyInner(MyOuter var1, int var2) {
        this.this$0 = var1;
        this.val$finalI = var2;
    }

    public void innerMethod() {
        System.out.println(this.val$finalI);
    }
}

版权声明:本文为qq_41171409原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。