JAVA篇学习之61-75

面向对象

什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
  • 抽象
  • 三大特性:
  1. 封装
  2. 继承
  3. 多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。

创建与初始化对象

  • 使用new关键字创建对象
  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
  1. 必须和类的名字相同
  2. 必须没有返回类型,也不能写void
  • 构造器必须要掌握
public class student {
    //属性:字段
    String name;//null
    int age;//0
    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}
public class application {
    //一个项目应该只存在一个main方法
    public static void main(String[] args) {
        //类:抽象的,实例化
        //类实例化后会返回一个自己的对象
        //student对象就是一个student类的具体实例
        student xiaoming = new student();
        student xh = new student();

        xiaoming.name="小明";
        xiaoming.age=3;

        System.out.println(xiaoming.name);
        System.out.println(xiaoming.age);

        xh.name="小红";
        xh.age=3;

        System.out.println(xh.name);
        System.out.println(xh.age);
    }
}

构造器详解

在Java中,构造器(Constructor)是一种特殊的方法,用于在创建对象时初始化对象的状态。构造器的名称与类名相同,并且没有返回类型,包括无参构造器有参构造器两种类型。

无参构造器

如果在类中没有显式地定义任何构造器,Java会为该类提供一个默认的无参构造器。无参构造器不接受任何参数,通常用于初始化对象的默认状态

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

    // 默认的无参构造器
    public Person() {
        // 初始化对象的默认状态
        this.name = "Unknown";
        this.age = 0;
    }
}

在上面的例子中,Person类提供了一个默认的无参构造器,用于初始化nameage属性的默认值。

有参构造器

除了默认的无参构造器外,我们还可以在类中定义有参构造器,用于接受参数并初始化对象的状态。

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

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

在上面的例子中,Person类提供了一个有参构造器,用于接受nameage参数,并初始化对象的状态。

Java创建对象内存分析

对象的内存分配

当我们使用new关键字创建一个对象时,Java会在内存中分配一块连续的空间来存储对象的实例变量。这块空间通常被称为堆(Heap),它是Java中用于存储对象的主要内存区域。

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

// 创建对象
Person person = new Person();

在上面的例子中,我们创建了一个Person对象,Java会在堆内存中为该对象分配空间,用于存储nameage实例变量。

内存分配示意图

  堆内存
+--------------+
|   Person     |
|--------------|
|   name       |
|   age        |
+--------------+
^
|
person引用变量

在上面的示意图中,堆内存中存储了Person对象的实例变量,而person引用变量存储了对象在内存中的地址。


封装

该露的露,该藏的藏

  • 我们程序设计要求“高内聚,低耦合”。高内聚就是类的内部操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

封装(数据的隐藏)

  • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏

记住这句话:属性私有,get/set


什么是继承?

在面向对象编程中,继承是一种重要的概念,它允许一个类(称为子类)继承另一个类(称为父类)的属性和方法。子类可以使用父类的属性和方法,同时还可以添加新的属性和方法,或者重写父类的方法。通过继承,我们可以实现代码的重用,提高代码的可维护性和灵活性。

在Java中,使用extends关键字来实现继承。下面是一个简单的例子:

public class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

public class Dog extends Animal {
    public void bark() {
        System.out.println("Dog is barking");
    }
}

在上面的例子中,Dog类继承了Animal类,因此Dog类可以使用Animal类中的eat方法。


super关键字详解

在Java中,super关键字用于引用父类的属性和方法。通过super关键字,子类可以访问父类的属性和方法,或者调用父类的构造器。

访问父类的属性和方法

子类可以使用super关键字来访问父类中的属性和方法。下面是一个简单的例子:

public class Animal {
    protected String name;

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

public class Dog extends Animal {
    private int age;

    public Dog(String name, int age) {
        super(name); // 调用父类的构造器
        this.age = age;
    }

    public void display() {
        System.out.println("Name: " + super.name); // 访问父类的属性
    }
}

在上面的例子中,Dog类通过super.name访问了父类Animal中的name属性。

调用父类的构造器

子类可以使用super关键字来调用父类的构造器。在子类的构造器中使用super关键字来调用父类的构造器,以便完成对父类属性的初始化。

public class Animal {
    protected String name;

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

public class Dog extends Animal {
    private int age;

    public Dog(String name, int age) {
        super(name); // 调用父类的构造器
        this.age = age;
    }
}

在上面的例子中,Dog类的构造器中使用super(name)调用了父类Animal的构造器,完成对父类属性的初始化。


方法重写

方法重写是面向对象编程中的一个重要概念,它允许子类重新定义父类中的方法。当子类重新定义(覆盖)父类的方法时,子类的对象调用该方法时将执行子类中的方法实现,而不是父类中的方法实现。方法重写可以实现多态性,提高代码的灵活性和可扩展性。

在Java中,方法重写的规则如下:

  1. 子类的重写方法必须与父类的被重写方法具有相同的名称、参数列表和返回类型
  2. 子类的重写方法不能使用比父类的被重写方法更严格的访问权限(例如,父类方法是public,子类方法不能是private)。
public class Animal {
    public void makeSound() {
        System.out.println("Animal is making a sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog is barking");
    }
}

在上面的例子中,Dog类重写了Animal类中的makeSound方法。

多态

多态是面向对象编程中的一个重要概念,它允许使用父类的引用来引用子类的对象。多态性在编程中提供了灵活性,允许我们在不同的情况下使用相同的代码来处理不同类型的对象。

在Java中,多态性通常通过继承和方法重写来实现。在多态性中,父类的引用可以指向子类的对象,父类的方法可以被子类重写,从而实现对子类对象的调用。

多态存在的条件:

  1. 继承关系:多态是建立在继承关系之上的,也就是说,必须存在父类与子类之间的继承关系。子类可以继承父类的属性和方法,从而可以通过父类的引用来引用子类的对象。

  2. 方法重写:多态还要求子类重写(覆盖)父类的方法。在多态的情况下,父类的引用可以指向子类的对象,并调用被子类重写的方法,从而实现对不同子类对象的统一处理。

public class Animal {
    public void makeSound() {
        System.out.println("Animal is making a sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog is barking");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat is meowing");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        animal1.makeSound(); // 输出:Dog is barking
        animal2.makeSound(); // 输出:Cat is meowing
    }
}

在上面的例子中,animal1animal2Animal类的引用,但它们分别指向Dog类和Cat类的对象。通过多态性,我们可以调用makeSound方法来实现对不同子类对象的调用。


static关键字

static关键字可以用来修饰成员变量、成员方法和代码块。它的主要作用是创建静态成员,与类的实例对象无关,属于类本身。下面是static关键字的一些常见用法:

静态变量

静态变量是属于类的变量,被所有类的实例对象所共享。可以通过类名直接访问静态变量,无需创建类的实例对象。静态变量在内存中只有一份拷贝,所有实例对象共享这一份拷贝。

public class MyClass {
    public static int count = 0;
}

静态方法

静态方法属于类,不属于类的实例对象。可以通过类名直接调用静态方法,无需创建类的实例对象。静态方法不能访问非静态的成员变量和方法,因为它们在对象创建之前就已经存在。

public class MyClass {
    public static void printMessage() {
        System.out.println("This is a static method");
    }
}

静态代码块

静态代码块在类加载时执行,只执行一次。通常用于初始化静态变量或进行一些静态资源的加载工作。

public class MyClass {
    static {
        System.out.println("This is a static block");
    }
}

抽象类

抽象类是不能被实例化的类,它主要用于被其他类继承。抽象类可以包含抽象方法和非抽象方法。

抽象方法

抽象方法是没有方法体的方法,只有方法的声明。抽象方法必须在抽象类中声明,子类必须实现抽象方法。抽象方法的存在可以强制子类实现某些方法,从而提高代码的规范性和可维护性。

public abstract class Shape {
    public abstract double calculateArea();
}

非抽象方法

非抽象方法是有方法体的方法,可以在抽象类中直接实现。子类可以选择性地重写非抽象方法。

public abstract class Shape {
    public abstract double calculateArea();

    public void printMessage() {
        System.out.println("This is a shape");
    }
}

累死人

/***
 * _ooOoo_
 * o8888888o
 * 88" . "88
 * (| -_- |)
 *  O\ = /O
 * ___/`---'\____
 * .   ' \\| |// `.
 * / \\||| : |||// \
 * / _||||| -:- |||||- \
 * | | \\\ - /// | |
 * | \_| ''\---/'' | |
 * \ .-\__ `-` ___/-. /
 * ___`. .' /--.--\ `. . __
 * ."" '< `.___\_<|>_/___.' >'"".
 * | | : `- \`.;`\ _ /`;.`/ - ` : | |
 * \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 * `=---='
 * .............................................
 *           佛曰:bug 泛滥,我已瘫痪!
 */

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值