Java面向对象

Java面向对象

前言

​ 面向对象是相对于面向过程来说的。面向过程思想即分析解决问题的具体步骤,然后根据步骤设计解决问题的具体思路和方法,一步一步地解决问题;面向对象思想则是将现实世界抽象成一个个对象,研究每个对象的属性和行为,描述对象在整个解决问题的过程中的行为。

​ 对于复杂事物的描述,为了从宏观上把握系统的整体架构,我们通常使用面向对象的思想来分析整个系统,但是,细化到解决问题的具体步骤,我们仍然需要使用面向过程的思想去处理具体问题。

1.什么是面向对象

面向对象编程:OOP-----Object Oriented Programming

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

核心思想:抽象

三大特性:封装、继承、多态

2.方法

2.1方法的定义

修饰符 返回值类型 方法名(形参列表){

​ 方法体;

​ return 返回值;

}

返回的数据要和定义的返回值类型一致,当方法不需要返回值是,用void关键字定义方法;

形参列表可以为空,也可以定义多个参数,多个参数之间用逗号隔开;

return关键字有结束方法的作用,当方法执行过return语句后,就代表方法执行结束。

方法名命名规范:

  • 由字母、数字、$(美元符)、_(下划线)组成
  • 不能以数字开头
  • 不能定义为Java中的关键字和保留字
  • 首字母小写,驼峰式命名(多个单词组成时,后面每个单词首字母大写)
  • 见名知意
  • 例:myMethod()

2.2方法的调用

  • 静态方法

    ​——用static关键字修饰的方法

    ​可以直接通过类名.方法名()调用

package com.th.oop;

public class Teacher {
    // 静态方法
    public static void teach(){
        System.out.println("老师正在上课");
    }
}
package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 直接通过类名调用静态方法
        Teacher.teach();
    }
}
  • 非静态方法

    ——没有使用static关键字修饰的方法

    实例化方法所在类的对象,通过对象名.方法名()调用

package com.th.oop;

public class Student {
    // 非静态方法
    public void study(){
        System.out.println("学生正在学习");
    }
}
package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 实例化一个学生类的对象
        Student student = new Student();
        // 通过student对象调用Student类中的study()方法
        student.study();
    }
}

3.类与对象

3.1类与对象的关系

​ 在Java中,类是一种抽象的引用数据类型,它并不能代表某一具体的事物,而代表了一类事物,它是对一类事物整体的描述和定义。

​ 对象是类的具体实例,能够表现出具体的属性和行为,而非一个抽象的概念。

3.2对象的创建与初始化

3.2.1类的创建

类由属性和方法组成

package com.th.oop;

public class Student {
    // 属性,也叫字段
    String name;
    int age;
    
    // 方法
    public void study(){
        // this代表当前类
        System.out.println(this.name + "正在学习");
    }
}
3.2.2对象的创建

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

package com.th.oop;

public class Test {
    public static void main(String[] args) {
        /*
         * 通过new关键字实例化一个Student类的对象
         * 类实例化之后会返回一个自己类型的对象
         * xiaoming对象就是Student类的一个具体实例
         * xiaohong对象也是Student类的一个具体实例,这里只是用作测试,方便理解,实际中不建议使用拼音给变量命名
         */
        Student xiaoming = new Student();
        Student xiaohong = new Student();
    }
}
3.2.3构造方法

类中的构造方法也叫构造器,在类进行实例化对象的时候一定会调用类的构造方法。

构造方法的特点:

  • 构造方法的名字必须和类名相同
  • 构造方法没有返回值,也不能写void

构造方法的作用:

  • 使用new关键字创建对象的过程,其本质就是调用类的构造方法
  • 初始化对象的值

注意点:

  • 类本身默认存在一个无参构造方法,当在类中定义了有参构造方法之后,本来类中默认存在的无参构造方法就不存在了,此时就无法使用无参构造方法实例化对象,若想要使用无参构造方法,就需要在类中显式定义一个无参构造方法。
package com.th.oop;

public class Person {
    String name;
    int age;

    // 显式定义无参构造方法
    public Person() {
    }

    // 定义类的有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 调用无参构造方法创建对象
        Person person = new Person();
        // 手动为对象的属性赋值
        person.name = "小明";
        person.age = 5;

        // 调用有参构造方法创建对象
        new Person("张三", 18);
    }
}
3.2.4方法的重载

​ 在同一个类中,方法名相同,参数列表不同的多个方法构成重载。

package com.th.oop;

public class OverLoadTest {
    // 定义第一个方法,这里为了方便测试,将方法定义为静态方法,实际上,方法是否构成重载与static没有关系
    public static int add(int a, int b) {
        return a + b;
    }

    // 定义与第一个方法名称相同,参数类型不同的方法
    public static double add(double a, double b) {
        return a + b;
    }

    // 定义与第一个方法名称相同,参数个数不同的方法
    public static int add(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        System.out.println("调用add(int, int)方法" + add(1, 2));
        System.out.println("调用add(double, double)方法" + add(1.0, 2.0));
        System.out.println("调用add(int, int, int)方法" + add(1, 2, 3));
    }
}

4.三大特性

4.1封装

​ 封装即属性私有化,使用private关键字修饰类的属性,使外部成员无法直接访问这些私有属性,对外只提供少量的方法供外部成员使用。

​ 程序设计追求高内聚,低耦合,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合即仅暴露少量方法供外部成员使用。

package com.th.oop;

public class Student {
    // 使用private关键字使属性私有化
    private String name; // 姓名
    private int age; // 年龄
    private char gender; // 性别

    /*
     * 定义get、set方法供外部成员使用
     * 可以自动生成,快捷键:Alt + Insert
     */
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }
}

封装的意义:

  • 提高程序的安全性,保护数据
  • 隐藏代码的实现细节
  • 提高代码的可维护性
  • 统一外部接口

4.2继承

​ 继承是类和类之间的一种关系,产生继承关系的两个类,一个为子类,一个为父类。子类使用extends关键字继承父类,extends有扩展之意,子类是父类的扩展,子类不仅继承了父类的非私有成员,子类还可以定义自己的属性和方法,拥有更丰富的功能。

​ Java中只存在单继承,一个子类只能继承一个父类,一个父类可以被多个子类继承。

父类:

package com.th.oop;

public class Person {
    // 父类定义属性
    String name;
    int age;

    // 父类定义方法
    public void say(){
        System.out.println("说话");
    }
}

子类:

package com.th.oop;

public class Student extends Person{
    // 子类可以定义自己的属性
    double high;
    double weight;

    // 子类可以定义自己的方法
    public void study(){
        System.out.println("学生在学习");
    }
}

测试:

package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 实例化子类Student对象
        Student student = new Student();

        // 子类对象可以调用父类的非私有属性和方法
        student.name = "小明";
        student.say();
        
        // 子类对象可以调用自己的属性和方法
        student.high = 168;
        student.study();
    }
}
this关键字和super关键字
  • this指代当前类对象的引用
    • 调用当前类的属性
    • 调用当前类的成员方法
    • 调用当前类的构造方法,只能放在第一行
  • super指代当前类的父类对象的引用
    • 调用父类的属性
    • 调用父类的成员方法
    • 调用父类的构造方法,只能放在第一行

4.3多态

方法的重写

​ 在继承的基础上,子类重新编写父类中方法的方法体,叫做方法的重写。

产生多态的条件:

  • 子类继承父类
  • 子类重写父类的方法
  • 父类的引用指向子类的对象

父类(Person):

package com.th.oop;

public class Person {
    // 父类定义属性
    String name;
    int age;

    // 父类定义方法
    public void say(){
        System.out.println("说话");
    }
}

子类(Student):

package com.th.oop;

public class Student extends Person {
    // 子类Student重写父类Person的say()方法
    @Override
    public void say() {
        System.out.println("学生说话");
    }
}

子类(Teacher):

package com.th.oop;

public class Teacher extends Person {
    // 子类Teacher重写父类Person的say()方法
    @Override
    public void say() {
        System.out.println("老师说话");
    }
}

测试:

package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 实例化子类Student对象和Teacher对象
        // 父类的引用指向子类的对象
        Person student = new Student();
        Person teacher = new Teacher();

        // 同是父类Person类型的对象,调用重写后的方法,产生不同的结果,这就是多态
        student.say();
        teacher.say();
    }
}
/*
 * 运行结果:
 *      学生说话
 *      老师说话
 */

5.抽象类与接口

5.1抽象方法

​ 使用abstract关键字定义的方法称为抽象方法,抽象方法没有方法体,必须定义在抽象类中。抽象方法本身没有任何意义,除非它被重写,在子类中实现其具体的功能。

package com.th.oop;

public abstract class Person {
    // 定义抽象方法
    public abstract void run();
}

5.2抽象类

  • 使用abstract关键字修饰类成为抽象类。
  • 抽象类除了可以定义抽象方法之外,其他方面与普通类并无区别。
  • 抽象类中可以定义属性和成员方法,也可以定义构造方法。
  • 抽象类中所有的抽象方法必须由其非抽象子类实现。
  • 抽象类可以作为数据类型。
  • 抽象类不能被实例化。

抽象类Person:

package com.th.oop;

public abstract class Person {
    // 定义属性
    String name;
    int age;

    // 定义常量
    public static final int LEG_NUMBER = 2;

    // 定义抽象方法
    public abstract void run();

    // 定义成员方法
    public void say() {
        System.out.println("说话");
    }

    // 定义无参构造方法
    public Person() {
    }

    // 定义有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

非抽象子类Student:

package com.th.oop;

public class Student extends Person {
    // 重写父类Person的抽象方法
    @Override
    public void run() {
        System.out.println("学生跑步");
    }
}

5.3接口

  • 接口可以看作是纯粹的抽象类。
  • 接口使用interface关键字进行定义。
  • 接口中只能定义抽象方法和常量。
  • 接口中定义的抽象方法默认使用public abstract关键字修饰,可以省略。
  • 接口中定义的常量默认使用public static final关键字修饰,可以省略。
  • 接口中的抽象方法由其实现类重写来实现其功能。
  • 接口是多继承,多实现的。一个接口可以继承多个接口,也可以被多个类实现,一个类也可以实现多个接口。

接口:

package com.th.oop;

public interface Behavior {
    // 定义常量,默认使用public static final关键字修饰,可以省略
    public static final int LEG_NUMBER = 2;

    // 定义抽象方法,默认使用public abstract关键字修饰,可以省略
    public abstract void run();
}

实现类Student:

package com.th.oop;

public class Student implements Behavior {

    // 重写接口Behavior中的抽象方法
    @Override
    public void say() {
        System.out.println("学生说话");
    }

    @Override
    public void run() {
        System.out.println("学生跑步");
    }
}

实现类Teacher

package com.th.oop;

public class Teacher implements Behavior{

    // 重写接口Behavior中的抽象方法
    @Override
    public void say() {
        System.out.println("老师说话");
    }

    @Override
    public void run() {
        System.out.println("老师跑步");
    }
}

测试:

​ 接口的引用可以指向实现类的对象,调用重写后的方法,产生不同的结果,实现多态。

package com.th.oop;

public class Test {
    public static void main(String[] args) {
        // 实例化实现类Student对象和Teacher对象
        // 接口的引用可以指向实现类的对象
        Behavior student = new Student();
        Behavior teacher = new Teacher();

        student.say();
        teacher.say();
    }
}
/*
 * 运行结果:
 *      学生说话
 *      老师说话
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值