Java面向对象

面向过程&面向对象

  • 面向过程思想

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

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。

    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

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

什么是面向对象

  • 面向对象编程(Object-Oriented Programming, OOP)

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

  • 先有具体的对象,然后抽象各个对象之间象的部分,归纳出通过类在认识其他对象。

  • 三大特性

    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。

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

类和对象的关系

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

    • 动物、植物、手机、电脑......
    • Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为
  • 对象是抽象概念的具体类

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

创建与初始化对象

  • 使用new关键字创建对象

  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。

  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩个特点:

    • 必须和类的名字相同。

    • 必须没有返回类型,也不能写void。

  • 一个类即使什么都不写也存在一个构造器。

        类名 对象名 = new 类名();//new +构造器

三大特性

封装

通常,禁止直接访问一个对象中数据的实际表现,而是应该通过操作接口来访问,这称为封装。alt+insert可以直接构造get和set方法。

属性私有,get/set。

封装方便维护,提高安全,便于拓展协作。

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("小红");//小红
        System.out.println(s1.getName());
        s1.setAge(155);//输入不合法
    }
}

public class Student {
    //属性私有 private
    //姓名
    private String name;
    //学号
    private int ID ;
    //性别
    private char sex;
    //年龄
    private int age;
    //提供一些可以操作这些属性的方法!
    //提供一些public的get,set方法。
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>0&&age<120){
            this.age=age;
        }else
            System.out.println("输入不合法");;
    }
}
  • 用途:
    • 提高程序的安全性,保护数据
    • 隐藏代码的实现细节
    • 统一接口
    • 系统可维护性增加了

继承

继承可以减少父类中重复性的代码。为了多态。

  • ctrl+H 可以查看结构树

  • 在JAVA中,所有的类都默认继承Object

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

  • extends的意思是扩展。子类是父类的扩展

  • Java中类只有单继承,没有多继承!一个父类可以有多个子类,一个子类只能有一个父类。

  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

  • 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

    public class 子类 extends 父类 {
        //子类拥有父类非 private 的属性、方法。
        //子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
        //子类可以用自己的方式实现父类的方法。
    }
    
    • super注意点

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

      • 代表的对象不同:

        • this:本身调用者这个对象

        • super:代表父类对象的应用

      • 前提

        • this没有继承也能使用

        • super只能在继承条件才可以使用

      • 构造方法

        • this()本类的构造
        • super()父类的构造

继承中,静态方法的调用只和左边定义的数据类型有关。非静态的方法会发生重写,且子类的权限只会和父类的相同或者更大。

  • 重写(需要有继承关系,子类重写父类的方法!)

    • 方法名必须相同
    • private、static和final无法被重写,private是私有的,无法被调用和重写。static属于类,不属于实例。final属于常量。
    • 参数列表必须相同
    • 修饰符:范围可以扩大:但是不能缩小。public>protected>default>private
    • 抛出的异常:范围可以被缩小,但不能扩大。

多态

多态就是声明一个父类的引用类型,指向一个子类,如果发生重写,指向哪个子类重写哪个方法。

  • 动态编译:类型:可拓展

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

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

  • 子类 可以调用自身的方法和父类的方法

  • 父类 只能调用自身的方法,不能调用子类独有的方法

  • 多态存在的条件

    • 有继承关系

    • 子类重写父类方法

    • 父类引用指向子类对象

  • 注意:多态是方法的多态,属性没有多态性

  • instance of (类型转换)引用类型,判断对象是什么类型

    public class Application {
        public static void main(String[] args) {
    
            //Object>String
            //Object>Father>son
            //Object>Father>son1
            //instanceof 可以判断是否有从属关系
            // 引用类型跟同级比较会直接报错
            Object object = new Son();
            System.out.println(object instanceof Son);//true
            System.out.println(object instanceof Son1);//false
            System.out.println(object instanceof Father);//true
            System.out.println(object instanceof Object);//true
            System.out.println(object instanceof String);//false
            System.out.println("=================================================");
            Father father = new Son();
            System.out.println(father instanceof Son);//true
            System.out.println(father instanceof Son1);//false
            System.out.println(father instanceof Father);//true
            System.out.println(father instanceof Object);//true
            //System.out.println(father instanceof String);//编译报错
            Son son =new Son();
            System.out.println(son instanceof Son);//true
            //System.out.println(son instanceof Son1);//编译报错
            System.out.println(son instanceof Father);//true
            System.out.println(son instanceof Object);//true
            //System.out.println(son instanceof String);//编译报错
        }
    
    }
    
public class Application {
    public static void main(String[] args) {
        Son son = new Son();
        Father father = new Son();
        Father father1 = new Father();
        son.run();//调用son
        father.run();//调用son
        father1.run();//调用father
    }
}

static

  • 可以修饰成员变量,方法,代码块,内部类
    • static修饰的成员变量,称之为类成员(类变量);非static修饰的称之为实例成员。
    • static修饰的成员变量,在加载类的字节码文件时候,就会进行分配内存,而且只分配一次;被类的所有对象共享;因此static修饰的成员是属于整个类的,不属于某个具体对象的。
    • static修饰的方法,称之为静态方法;静态成员(包括成员变量、静态方法)可以通过类名直接访问,也可以通过对象名访问。
    • 静态成员不能访问实例成员(非静态),实例成员可以访问静态成员。
    • static可以修饰代码块,称之为静态代码块;静态代码块只执行一次;最先执行静态代码块,然后执行代码块,最后执行构造方法。
public class Person {
    {
        System.out.println("匿名代码块");
        //代码块(匿名代码块)
    }
    static {
        System.out.println("静态代码块");
        //静态代码块
        //只执行一次
        //可以赋一些初始值
    }

    public Person() {
        System.out.println("构造器");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("======================");
        Person person2 = new Person();

    /*
    执行顺序
    静态代码块(只执行一次)
    匿名代码块
    构造器
    ======================
    匿名代码块
    构造器
         */
    }
}

final

  • final 可以修饰变量,方法,类

    • Java中使用final修饰的变量称之为常量。

    • final修饰基本类型的变量,不能重新赋值。

    • final修饰的引用类型的变量,对象的引用不能发生改变(不能重新new对象)。

      final Book b = new Book();
      b.setBookName("sss");
      b = new Book();//编译错误
      
    • final修饰变量的初始化

      • 在声明的同时初始化
      • 在代码块中初始化
      • 在构造方法中初始化
      • 如果修饰的是局部变量,在使用前初始化
public class Student {
    private static int age;
    private double score;

    public void run(){
    }
    public static void eat(){
    }
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.age);
        System.out.println(student.score);
        System.out.println(Student.age);
        //System.out.println(Student.score);报错 无法调用非静态变量
        eat();
        //run();报错 static和类一起加载,而没有static时,类加载时还没有这些方法。
    }
}
package opp.demo07;
//静态导入包
import static java.lang.Math.random;
public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());//正常写法,如果不不想输入Math,可以静态导入包
        System.out.println(random());.
    }
}

抽象类

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

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。

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

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

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

    public abstract class Action {
        //约束 让子类来继承
        //只有方法的名字,没有方法的实现
        //abstract抽象类 extends:单继承 接口:可以多继承
        public abstract void dosomething();
        //1.不能new这个抽象类,只能靠子类来实现他
        //2.抽象类中可以写普通的方法
        //3.抽象方法必须在抽象类中
    }
    

接口

  • 普通类:只有具体实现

  • 抽象类:具体实现和规范(抽象方法)都有!

  • 接口:只有规范,自己无法写方法专业的约束!约束和实现分离:面向接口编程

  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是...则必须能..”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。

  • 接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、Java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

  • 声明类的关键词是class,声明接口的关键字是interface。

    package opp.demo09;
    //抽象类:extends
    //类 可以实现接口 implements
    //实现了接口的类,就需要重写接口中的方法
    //接口可以实现伪多继承
    public class UserserviceImplements implements UserService,TimeService{
        @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 opp.demo09;
    //抽象的思维 Java
    //interface 定义的关键字,接口都需要有实现类
    public interface UserService {
        //接口中的定义都是抽象的,public abstract
        void add(String name);
        void delete(String name);
        void update(String name);
        void query(String name);
        //接口中定义的所有属性都是常量,public static final
        //一般不会在接口中定义常量
        int AGE = 99;
    }
    
  • 接口的作用

    • 约束
    • 定义一些方法,让不同的人实现~
    • public abstract 方法
    • public static final 属性
    • 接口不能被实例化,接口中没有构造方法
    • implements可以实现多个接口
    • 必须要重写接口中的方法

内部类


public class Outer {
    private int ID;
    public void out(){
        System.out.println("外部类");
    }
    public  class inner{
        public void in(){

            System.out.println("内部类");
        }
        //获取外部类的私有属性
        public void getID(){
            System.out.println(ID);
        }

    }
}
public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //new 内部类
        Outer.inner inner = outer.new inner();
        inner.getID();
    }
}
public class Test {
    public static void main(String[] args) {
        //匿名内部类:没有名字初始化类,不用将实例保存到变量中
        new Apple().eat();
        new UserService(){
            //重写方法
        };
    }
}
//一个类中只能有一个public class,但是可以有多个class
class Apple{
    public void eat(){
        //局部内部类:定义在方法中的内部类。
        class Inner{

        }
        System.out.println("1");
    }
}
interface UserService{

}
posted @ 2021-08-21 05:39  beamsoflight  阅读(23)  评论(0)    收藏  举报