第二十三讲——面向对象(oop)

第二十三讲——面向对象(oop)


1——什么是面向对象

—面向过程 & 面向对象

  • 面向过程思想

以类的方式组织代码,以对象的组织(封装)数据

​ 线型思想,一步一步实施。

适合处理简单问题。

三大特性;

封装 | 继承 | 多态

  • 面向对象思想

​ 面对复杂和大型的任务,将任务一一拆解为一个个小任务再拆解直至适合解决任务的思想。最终最底层的的面对思想方法还是要用面向过程来解决。

合适处理复杂的问题,与多人协作的问题。


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


—方法调用

方法调用是指在调用其他类或包中类方法所用的方法


package Test;
import Test01.Person01;
public class Application {
    public static void main(String[]args){
    //同一个package下  调用非静态方法
        /**一. 暴力添加static调用
        类名.方法名
        Person.shout();
          二.  new方法(本质在调用构造器)
          实例化对象,才会使不存在的方法实例化
          new 类名();//按atl+Enter
        Person person = new Person();
        对象名.方法名;
        person.shout();
         */
     //不一个package下  调用非静态方法
        /**
         *方法一;  添加static
         * 1. import Test01.Person01;—>添加static—>Person01.shout();
         *      类名.方法名;
         *      Person01.shout();
         *方法二;  new方法
         *        Person01 person01 = new Person01();
         *         person01.shout();
         * */
    }
}

特殊情况

package OOP;

public class Demo01 {
    public static void main(String[]args){
        //都是静态或非静态才能直接调用
    }
    //====================================
    //static 和类一起加载的
    public static void a(){
        b();//这里调用了方法b
   //然而一个静态的方法调用非静态的方法是会报警出错的
        //即一个存在的方法调用了一个不存在的方法
    }
    //类实例化 之后才存在的
    public void b(){

    }
}

—形参 &实参


—值传递 & 引用传递

package OOP;
//值传递
public class Demo01 {
//形参 & 实参
    public static void main(String[]args){
        int i = 0;
        System.out.println(i);//0
        //Demo01. 加与不加都可以 不知道为什么加 就加吧
        Demo01.change(i);
        System.out.println(i);//0
        //因为java是值传递到最后还是0

    }
    //返回为空
    public static void change(int a ){
         a = 10;
    }
}

2——类与对象的创建

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

  • 动物、植物、person、细菌......
  • 动物类、植物类、person类、细菌类。用来描述\定义某一种具体事务应该具有的特点和行为

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

  • 张三就是person类一个具体实例,张三家里的旺财就是🐕的具体实例
  • 能体现出特点,展现出功能的是具体的实例,而不是抽象的概念

创建与初始化对象

一个程序只有一个主启动类(一个main方法);

public class Test23{
    //一个程序只有一个主启动类(一个main方法);
public static void main(String[]args){
        
      }
}


package Base;
public class Base2300 {
    //一个程序只有一个主启动类(一个main方法);
    public static void main(String[]args){
        //抽象的类需要实例化
        //类实例化后会返回一个自己的对象
        //student对象就是一个Student类的具体实例
        Student 小明 = new Student();
        Student 小红 = new Student();
        //同一个类可以有不同的属性
        System.out.println(小明.name);//null
        System.out.println(小红.age);//0
        //使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化 以及对类中构造器的调用
        小明.name = "小明";
        System.out.println(小明.name);
        小明.age = 6;
        System.out.println(小明.age);
    }
}

package Base;

public class Student {
    //一个类中只有属性和方法
    //属性
    String name;
    int age;

    //方法
    public void study() {
        //this指当前的类中的东西
        System.out.println(this.name + "在学习");
    }
}

print

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Base.Base2300
null
0
小明
6

Process finished with exit code 0


3——构造器

构造器叶称为构造方法,是在进行创建对象时候必须调用的

构造器有两个特点;

  • 必须和类名字相同
  • 必须没有返回类型也不能写void

—构造器的特点

说明一个类即使什么也没写也会存在一个方法

  • 构造器的特点

1.与类名称相同

2.没有返回值 也没有void


—构造器的作用

  • 使用new关键字 本质是调用构造器
  • 用来初始化值
package Test.Test;
//java——>查看class文件
public class Person {
    //1.与类名称相同
    //2.没有返回值 也没有void
    String name;
    //1.使用new关键字 本质是调用构造器
    //2.用来初始化值

    //()无参数           无参构造
    //一旦定义了无参构造 无参必须显示定义
    public Person(){//重载
        this.name = "小次郎";
    }
    //()有参数  有参构造
    public Person(String name){
        this.name = name;
    }

}

/**
 * package Test.Test;
 *
 * public class Application {
 *     //一个程序应该只有一个主方法(main)
 *     public static void main(String[]args){
 *         //new 实例化了一个对象
 *         Person person = new Person();
 *         //()为null所以调用无参构造 小次郎
 *         System.out.println(person.name);
 *         Person person1 = new Person("大聪明");
 *         System.out.println(person1.name);
 *     }
 * }
 *
 * 构造器特点;
 *    1.和类名相同
 *    2.没有返回值 没有void
 * 作用;
 *    1.new 本质在调用构造方法
 *    2.初始化对象的值
 * 注意点;
 *    1.定义有参构造后,必须写入参数 ,否则,必须添加无参构造器
 * 快捷键;
 *     alt+insert 添加构造方法
 *     
 */


print

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.Test.Application
小次郎
大聪明

Process finished with exit code 0

—alt+insert快捷键

package Test.Test;
public class Person {
    //===alt+insert 快捷键===

    // 属性
    String name;
    int age;

    //方法   按alt+insert 快捷键生成

    //选择 SelectNone
    public Person() {
    }
    //选择OK
    public Person(String name) {
        this.name = name;
    }
    //按住Ctrl 选择两个参数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

/**
 * package Test.Test;
 *
 * public class Application {
 *     //一个程序应该只有一个主方法(main)
 *     public static void main(String[]args){
 *         //new 实例化了一个对象
 *         Person 晓忠 = new Person("晓忠");
 *         System.out.println(晓忠.name);
 *         Person person = new Person();
 *         System.out.println(person.name);
 *         Person person1 = new Person("小红",12);
 *         System.out.println(person1.age);
 *     }
 * }
 * =============================================
 * 
 *C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.Test.Application
 * 晓忠
 * null
 * 12
 *
 * Process finished with exit code 0
 */

4——对象和类小结

/**
 * 1. 对象与类
 * 类是一个模板——抽象  对象是具体的实例——具体        
 * 2. 方法
 * 定义、调用
 * 3. 对象的引用
 * 引用类型;  基本类型(8)整数型 浮点数 字符型 boolean
 * 对象是从引用来操作的; 栈---->堆
 * 4. 属性; 成员temp
 *  默认初始化;
 *       data; 0  0.0
 *       char; u0000
 *       boolean; false
 *       引用; null
 *   修饰符; 属性类型 属性名 = 属性值
 * 5. 对象的创建和使用
 *    - 必须使用new 关键字 创造对象, 构造器 Person 校花 = new person();
 *    - 对象的属性 校花.name;
 *    - 对象的方法 校花.sleep();
 * 6. 类;
 *   属性
 *   方法
 * */

5——封装(数据的隐藏)

  • **高内聚; 类的内部数据操作由自己完成,不允许外部干涉 **

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

    就是将代码藏起来,给Users使用统一接口来访问。

    属性私有,get/set


package Test;
public class Application{
    public static void main(String[]args){
        Person s1 = new Person();
        //s1.name = 12;不是public 是private所以不能赋值  报错
        s1.getName("晓忠");
        System.out.println(s1.setName());
        //==================================
        //设置年龄越限问题
        s1.setAge(999);
        System.out.println(s1.getAge());
        /**
         * 1. 提高程序的安全性,保护数据
         * 2. 隐藏代码的实现细节
         * 3. 统一接口
         * 4. 系统可维护增加
         * */

    }
}

package Test;
public class Person{
    //public 公共的 private 私有的
//属性
    private String name; // 名字
    private int id;      // 学号
    private  char sex;   // sex
    private  int age;
//方法
    //提供一些可以操作属性的方法
    //提供一些public 的 get set方法
    //get  获取这个数据
    public String setName(){
        return this.name;
    }
    public void getName(String name){
        this.name = name;
    }
    //alt + insert 选择get+set可以生成方法

    public int getAge() {
        return age;
    }
    //可以约束数据 规范数据
    public void setAge(int age) {
        if(age>120 || age<0){
            this.age = 3;
        } else{
            this.age = age;
        }
    }
}



  • 用private来,设置属性
  • 用 get/set 来获取和输入数据
  • 以及set数据的规范

6——继承(extends)

类是一批对象的抽象; 而继承是一批类的抽象

  • 子类继承了父类,就会拥有父类的全部方法

  • JAVA中只有单继承,没有多继承,一个类只有一个父类,可以有多个子类

类与类的关系有;

继承

组合

聚合等等、、、


—继承的使用

  • 格式
public class Student extends Person{
    //子类 extends 父类
}

/** 
  作用
    — 可以继承父类的所有方法
*/


—Extends 中的 Public and Private

public; 公共的

private; 私有的


  • 名字是private 是私有的不允许自接被继承 需要添加 get set方法来操作

    /*
    拓展修饰符
      -public  最高级
      -protected  受保护的
      -default 默认的 | 不符合的
      -private 私有的
    */
    
  • extends的get and set


—extends 三大重点

extends 三大重点

  • Object
  • super
  • 方法重写

Object

public class Persoon /*extends Object*/

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

Super

—调用父类—属性


—调用父类—方法

—super 特性

Super注意点:

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

Vs this:

this; 本身掉调用者这个对象
super; 代表父类对象的应用

前提;

this; 没用继承也可以使用
super; 只能在继承条件才可以使用构造方法
this(); 本来的构造
super(); 父类的构造


方法重写

重写是指方法的重写与属性无关

只有非静态才有重写!!!

子类重写了父类的方法,执行子类的方法

非静态重写


静态

静态小结;

//A子类 B父类
A a = new A();
//======
B a = new A();
  • 静态方法;方法的调用只和左边,定义的数据类型有关

  • 静态方法;父类的引用可以指向子类

    B b= new A();
    
  • 重写是指方法的重写,与属性无关


/**
 * 重写; 需要继承关系,字类重写父类的方法
 *      1. 方法名必须 相同
 *      2. 参数列表必须相同
 *      3. 修饰符; 范围可以扩大但不能缩小: public>Protected>Default>private
 *      4. 抛出的异常: 范围。可以被缩小,不能扩大; ClassNotFoundException/找不到类-->Exception(大)
 *
 * 重写: 子类与父类的方法必须一致,方法体不同!!
 *
 * 为什么需要重写;   父类的功能,子类不一定需要,或者不一定满足
 *
 *     快捷键Atl+insert 选择 Override
 * */

7——多态

  • 多态编辑: 类型:可拓展性

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式

  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类 | 相关类)

  • 多态存在的条件

    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
  • 和重写一样,属性没有多态性

  • 只有父类和子类 有联系的才有多态, 要防止转换异常 ClassCastException

    1. static 方法,属于类 不属于实例 所以不能做重写
    2. final 常量 在常量池里 也不许做重写
    3. private 私有的不能做重写


8——instanceof和类型转换

instanceof

    /**
     * instanceof : 判断类型是否存在父子关系
     * true:  存在父子关系
     * false: 有关系 不是父子关系
     * 报错: 引用类型同级报错 || 其他报错
     * */

package Test.demo08;
//Teacher类与Student类继承Person
public class Application {
    /**
     * instanceof : 判断类型是否存在父子关系
     * true:  存在父子关系
     * false: 有关系 不是父子关系
     * 报错: 引用类型同级报错 || 其他报错
     * */

    public static void main(String[]args){
        Object object = new Student();
        //Object > Person > Student
        //Object > Person > Teacher
        System.out.println("===object==========================");
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false
        System.out.println("===person==========================");
        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(person instanceof String); //引用类型同级报错
        System.out.println("===student==========================");
        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);  //  其他报错
    }
}

print

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo08.Application
===object==========================
true
true
true
false
false
===person==========================
true
true
true
false
===student==========================
true
true
true

Process finished with exit code 0


类型转换

package Test.demo09;

public class Application {
    public static void main(String[]args){
        //====类型转换=====   父<———>子 高<———>低
        Student s1 = new Student();
        s1.go();//子类的go
        s1.run();//父类的run
        //===================================
        //==================================
        Person p1 = new Student();//父类的引用指向子类
        /**
         * 父类———不能直接调用———>子类
         *    p1.go();//false 需要将Person这个对象转换为Student类型,就能使用Student的方法了
         * 高————>低     需要强制转换
         * */
        System.out.println("===高——>低==父——>子====================");
        ((Student)p1).go();
        p1.run();
    }
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo09.Application
go
run
===高——>低==父——>子====================
go
run

Process finished with exit code 0

子类转换成父类可能会丢失一些自己本来的方法


9——Static关键字详解

  • static 在类中使用是修饰成员变量
  • 加在方法上是静态方法
  • 加在属性上是静态属性

—关于属性

package Test01;
public class Student {
    private static int age;//静态变量 需要很多类用到的话用static
    private double score;//非静态变量
    
    public static void main(String[] args) {
        System.out.println(Student.age);//直接调用的 static可以直接调用
        /** 使用  类名.属性名  
         以便知道是静态属性。*/
        System.out.println(age);
        
        //========非静态 new方法==============

        
        Student s1 = new Student();
        System.out.println(s1.age);//依据对象实例化后调用的
        System.out.println(s1.score);//依据对象实例化后调用的
    }
}

—关于方法

package Test01;

public class Test01 {
    public void go(){
        //非静态方法可以调用静态方法所有东西 非静态和类一起加载出来
    }
    public static void run(){
        //静态方法不能直接调用非静态方法  因为非静态和类一起加载 加载出来前都没有静态方法
        //静态方法可以调用静态方法
    }
    public static void main(String[]args){
        Test01.run();
        run();//静态方法可以直接调用
        //非静态调用
        new Test01().go();//新的调用格式
        Test01 t1 = new Test01();
        t1.go();


    }
}

—关于代码块

package Test01;

public class Demo01 {
        {  /***
         ——代码块(匿名代码块)——
         没有名字的代码块程序并不能主动的调用这个模块
         创建对象的时候就创建了
         在构造器之前
         */
            System.out.println("匿名代码块启动");
            //——作用赋予初始值
        }
        static {

            /**
             *   ————静态代码块 ————
             * 类一加载就直接执行
             * 永久只执行一次
             * */
            System.out.println("静态代码块启动");
        }

    public Demo01() {
        System.out.println("构造器启动");
    }
    public static void main(String[]args){
        Demo01 d1 = new Demo01();
        System.out.println("====分割线=============");
        Demo01 d2 = new Demo01();
    }
}

print

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test01.Demo01
静态代码块启动
匿名代码块启动
构造器启动
====分割线=============
匿名代码块启动
构造器启动

Process finished with exit code 0


package Test01;
//导入 Math具体方法就不用加Math
//import static java.lang.Math.random;
import static java.lang.Math.*;

public class Test02 {
    public static void main(String[]args){
        System.out.println(random());//会产生一个随机数
        System.out.println(PI);
        //Math.PI
    }
    /**
     * 关注官方文档就有好多玩法
     * */
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test01.Test02
0.615037571204595
3.141592653589793

Process finished with exit code 0


10——abstract/抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类那么该类就是抽象类。

  • 抽象类中可以没有抽象方法,到那时有抽象方法中类一定要声明为抽象类

  • 抽象类,不能使用new关键字来创建对象,它是用来子类继承的

  • 抽象方法,只有方法的声明没有方法的实现,它是用来让子类实现的

  • 子类继承抽象类那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类


11——接口

功能对比;

  • 普通类: 只有具体实现
  • 抽象类: 具体实现和规范(抽象方法)都有!
  • 接口 : 只有规范! 自己无法写方法!

什么是接口;

  • 接口就是规范,定义了一组规则,体现显示世界中 “如果是,则必须” 的思想。

  • 接口的本质是契约,和法律也要,制定后需要去遵守

  • OO(面向对象)的精髓是,是对对象的抽象,最能体现这一点的是接口。

package Test.demo11;
//

//利用接口实现 多继承
public class UserServiceImpl implements UserService,TimeService{
    //实现接口 需要重写方法 不然会报红 | 实现类公式  implements 接口名称
    @Override
    public void add(String name) {

    }
    @Override
    public void delete(String name) {

    }
    @Override
    public void update(String name) {

    }
    @Override
    public void query(String name) {

    }
    @Override
    public void timer() {

    }
}
/**
 * package Test.demo11;
 *
 * public interface TimeService {
 *     void timer();
 * }
 * */

package Test.demo11;
//calls类 换成interface 接口
public interface  UserService {
    //在接口定义的属性都是常量 final
    //public static final |  int age = 99;
    public static final int age = 99;

    void add   (String name);
    void delete(String name);
    void update(String name);
    void query (String name);

}
/**
 *   -接口不能写方法
 *   -接口中所有定义其实都是默认抽象的
 *   public abstract 自己写会标灰
 *   -{public abstract void add(String name)|  void add (String name)}
 *   -接口需要实现类———UserServiceImpl
 * */

作用

  • 约束
  • 定义一些方法,让不同的人实现~ 10 ---1有一个任务多种不同的实现方式
  • public abstract
  • public static final
  • 接口不能实例化(new)~ 接口中没有构造方法
  • implments 可以实现多个接口
  • 必须重写接口中的方法

12——N种内部类

  • 内部类就是在一个类的内部再定义一个类,比如在A类中定义一个B类,那么B类就是A类的内部类,而A类就是B类的外部类

    1. 成员内部类
    2. 静态内部类
    3. 局部内部类
    4. 匿名内部类

—成员内部类

package Test.demo12;

public class Application {
    public static void main(String[] args) {
        
        Outer outer = new Outer();
        //通过外部类来实例化内部类
        //outer.new Inner();  外部类对象名. new 内部类名();
        Outer.Inner inner = outer.new Inner();
        //内部类可以调用外部类的私有属性与方法
        inner.in();
        inner.getId();
        inner.getOut();
        
    }
}

//===============成员内部类===============================
package Test.demo12;
//Outer : 外部类
public class Outer {
    private  int id = 729;
    public void  out(){
        System.out.println("这是外部类的方法");
    }
    //Inner : 内部类
    class Inner{
        public  void in(){
            System.out.println("这是内部类的方法");
        }
        public void getId(){
            System.out.println(id);
        }
        public void getOut(){
            out();
        }
    }
}

显示

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo12.Application
这是内部类的方法
729
这是外部类的方法
Process finished with exit code 0

加static 就变成静态内部类


—局部内部类

package Test.demo13;

public class Outer {
    //局部内部类
    public void method(){
        class Inner{
            public void in(){

            }
        }
}
}

—匿名内部类

package Test.demo13;
//匿名内部类
public class Test {
    public static void main(String[] args) {
        /**
         *   Apple apple = new Apple();
         *   实例化了Apple类并赋值给对象apple 对象名是apple
         *   apple.eat();
         * */
        //匿名内部类 匿名对象的使用 这个对象没有名字
        //不用将实例保存到变量中
        new Apple().eat();
        new UserService(){
            @Override
            public void hello() {

            }
        };
        
    }
}
class Apple{
    public void eat(){
        System.out.println("Apple 12 Max Pro");
    }
}
interface UserService{
    void hello();
}

print

C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo13.Test
Apple 12 Max Pro

Process finished with exit code 0


—测试类

package Test.demo13;

public class Outer {

}
//Java类中只有一个public class类 但是可以有多个class类
//写测试类方便
class A{
    public static void main(String[] args) {
        
    }

}


新增单词

1 change 改变 劝G~
2 person 人类 佩尔森~
3 Application 应用 啊婆利K xun~
4 insert 插入 in射te~
5 Select 选择 塞阿克特~
6 None 一个也不;什么也不 诺内
7 SelectNone 一个也不选择 塞阿克特诺内 一个选项
8 cancel 取消 康塞尔~ 一个选项
9 sleep 睡觉 斯利普
10 private 私有的 怕维特~
11 sex 性别 傻克斯~
12 get 获取 给他~
13 set 设置 塞特~
14 say 说话 塞伊~
15 shout 吼叫 笑T~ .sout | 输入快捷方式区分开来
16 extends 继承 E克斯蛋丝~
17 refactor 重构 | 确认 瑞发可特~ 可以 和doctor 一起记
18 teacher 教师 ti却~ tea茶 char字符
19 Object 对象 熬不掘KT~ 所有的类都继承Object
20 super 超级 | 特级 指父类 | 联系superMan
21 Override 重写 偶夫掳爱的~ Over+ride记
22 instanceof 判断关系类型 因丝等次of~ (Student—instanceof —Person)是否有父子关系
23 Math.random() 产生随机数 乱蹬~ Math.random()
24 abstract 抽象的 啊不丝架可T~
25 dosomething 做某些事 do 桑 婶~
26 interface 接口 英特尔face intel 英特尔 | face脸
27 UserService 用户服务 User瑟维斯~
28 add a的~ 增删改查
29 delete
30 update up戴特~ date 日期
31 query kwei瑞~ very 非常 | query 查
32 implements 实现 英噗门次~ impl | 实现 缩写
33 Outer 外部类 | 外在的 凹特儿~
34 Inner 内部类 | 内在的 in 纳~
posted @ 2021-02-17 18:12  项晓忠  阅读(226)  评论(0编辑  收藏  举报