Java SE 入门到精通—面向对象【Java】

1.面向过程与面向对象

面向过程(Procedural Programming)面向对象(OOP)是两种不同的编程思维,它们有着不同的设计思想和实现方式。

面向过程是将程序的设计和实现建立在过程(或方法)的概念上,程序被组织为一系列方法,更注重于过程的执行,更适合于简单、直接的问题解决

面向对象是将程序的设计和实现建立在对象的概念上,将现实世界中的事物抽象为对象,每个对象都有自己的属性(数据)和行为(方法),通过调用每个对象的属性或方法去解决问题。这样的设计模式使得代码更加模块化、易于理解和维护。


举例来说,大象装进冰箱需要几步?

在这里插入图片描述

按照面向过程思想:
第一步:工作人员去打开冰箱门
第二步:把大象塞进冰箱
第三步:工作人员把冰箱门关上
这里我们就看出来了,面向过程就是把一件事按步骤一步一步来实现

用代码表示面向过程

    public void openDoor(){}  //开门
    public void putIn(){}       //装冰箱
    public void closeDoor(){}   //关门

用面向对象思想解决大象装进冰箱
在这里插入图片描述

按照面向对象思想:

冰箱作为一个对象;
大象作为一个对象。

冰箱有这些功能:开门、装物体、关门

用代码表示

class fridge{
    public void open(大象){}   //开门
    public void putIn(大象){}  //放进冰箱
    public void close(大象){}  //关门
}

class elephant{
	public void eat(){}   //吃
}

看出来了什么?每个对象是独立的,有属于它自己的功能,只需要专心实现自己的功能就好。所以在建立对象模型阶段,仅仅关注对象有什么的功能,但不考虑如何实现这些功能。


如果不懂,我再举个例子

例如我们可以把"猫"抽象对象来理解:

  1. 属性:猫的属性可以是它的颜色、体重、年龄等。
  2. 行为:猫的行为可以是它的叫声、移动等。

现在让我们用 Java 代码来实现一个简单的猫类:

// 定义猫类
public class Cat {
    // 属性
    private String color;
    private double weight;
    private int age;
    
    // 构造方法
    public Cat(String color, double weight, int age) {
        this.color = color;
        this.weight = weight;
        this.age = age;
    }
    
    // 方法:获取颜色
    public String getColor() {
        return color;
    }
    
    // 方法:获取体重
    public double getWeight() {
        return weight;
    }
    
    // 方法:获取年龄
    public int getAge() {
        return age;
    }
    
    // 方法:猫叫
    public void meow() {
        System.out.println("喵喵~");
    }
    
    // 方法:猫移动
    public void move() {
        System.out.println("猫在走动");
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        // 创建猫对象
        Cat myCat = new Cat("橘色", 4.5, 3);
        
        // 访问属性并输出
        System.out.println("我的猫的颜色是:" + myCat.getColor());
        System.out.println("我的猫的体重是:" + myCat.getWeight() + "kg");
        System.out.println("我的猫的年龄是:" + myCat.getAge() + "岁");
        
        // 调用方法
        myCat.meow();  // 输出:喵喵~
        myCat.move();  // 输出:猫在走动
    }
}

在上面的代码中,我们定义了一个 Cat 类,其中包括了猫的属性(颜色、体重、年龄)和行为(叫声、移动)。然后在 Main 类中,我们创建了一个猫的对象 myCat,并访问了它的属性和调用了它的方法。

这个例子就是面向对象的一个简单示例,通过对象来使得代码更加直观易懂,现在你明白了吗?

2.面对对象基本概念

2.面向对象基本概念

2.1访问修饰符

类修饰符:

  • private(私有访问控制符)只能在声明 private(内部)类。
  • [default] 默认,只有在同一个包中才可以访问,子类在其他包中则不可以访问。
  • protected(保护访问控制符)同一个包中的其他任何类以及任何子类(无论子类是在哪个包中声明的)可以访问。
  • public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类。
  • abstract,将一个类声明为抽象类,没有实现的抽象方法,需要子类提供方法实现。
  • final,将一个类生命为最终(即非继承类),表示他不能被其他类继承。
  • static,声明静态内部类,可以提供给外部类访问。

成员变量修饰符:

  • public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问。
  • protected(保护访问控制符)同一个包中的其他任何类以及任何子类(无论子类是在哪个包中声明的)访问。在子类中可以覆盖此变量。
  • private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。
  • final,最终修饰符,指定此变量的值不能变。
  • static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。
  • transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量,使该属性不参与序列化。
  • volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改。

方法修饰符:

  • public(公共控制符)。
  • private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类)。
  • protected(保护访问控制符)同一个包中的其他任何类以及任何子类(无论子类是在哪个包中声明的)进行访问。
  • final,指定该方法不能被重写(Override,子类继承父类)。
  • static,指定不需要实例化就可以激活的一个方法。不需要对象即可调用。
  • synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止多个线程的同时访问,运行结束后解锁。

另外在面向对象中

成员变量:类方法体外的变量,存于堆内存,有默认的初始化值(0,unll),局部变量存在栈空间,无默认值。

局部变量:类方法体内的变量,存于栈内存,无默认值,必须定义赋值后才可以使用,随方法的结束而消失。

实例成员必须通过实例对象调用(非 static 修饰)。

类成员可以通过类/实例对象调用(被 static 修饰)。

用 static 修饰的成员均为类成员,被该类共享(类变量,类方法…)。

2.2 关键字this与super

this

表示调用该方法的对象,方法被哪个对象调用,this就指向谁。

使栈内存中该对象指向堆内存中该对象的成员变量。

public class Student {
    private int age;
    public void method(int age) {
        this.age = age; // 添加 this 关键字,使前一个 age 成为成员变量,再将局部变量 age 赋值过去
    }
}

在局部变量和成员变量重名下用来指代成员变量一般多用于set,get方法以及一些设计模式

super

访问指向父类

super.成员变量1 //访问父类成员变量1

super(无参/带参) //访问父类无参或带参构造方法

super.方法() //访问父类无参或带参成员方法

2.3构造方法

用于初始化对象,该方法无返回值(特殊:不能用viod修饰),方法名必须和类名一致

无参构造与带参构造

构造方法用于初始化对象

package Demo;

public class Person {

    private String name;
    private int age;

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

    public static void main(String[] args) {
        System.out.println(new Person().name); //null
        System.out.println(new Person("坤坤",20).name); //坤坤
    }

}

类中最好创建一个无参构建方法,对后续一些事很方便

2.4方法重载

根据参数不同而调用的方法不同

只针对类型不同也可以用泛型方法实现

重载规则

方法名必须相同

Java允许重载任何方法(main,构造等等)

例如重载构造方法

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

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

2.5方法重写

重写父类某个方法(父类方法依旧可以使用super调用),其子类权限>=父类

例如重写toString方法

打印一个对象的时候,会自动调用该对象的toString()方法

    @Override
    public String toString() {
        return  name+String.valueOf(age);
    }
public class Pet {
	String name;
	String color;
	int age;
 
	// 四个不同的构造方法,这里用到了方法重载
	public Pet(String aName, String aColor, int aAge) {
		name = aName;
		color = aColor;
		age = aAge;
	}
 
	public Pet(String aName, int aAge) {
		name = aName;
		color = "white";
		age = aAge;
	}
 
	public Pet(String aName, String aColor) {
		name = aName;
		color = aColor;
		age = 2;
	}
 
	public Pet() {
		name = "Amy";
		color = "white";
		age = 1;
	}
        //重写toString方法以便格式化输出
	public String toString() {
		return "name=" + name + " color=" + color + " age=" + age;
	}
 
	public static void main(String[] args) {
		// 使用不同的构造方法初始化对象,程序会根据参数的不同选择正确的构造方法
		Pet pet1 = new Pet("Jack", "black", 2);
		Pet pet2 = new Pet("Dam", "purple");
		Pet pet3 = new Pet("John", 3);
		Pet pet4 = new Pet();
		// 打印查看結果,注意:如果沒有重写toString方法,直接打印对象不能打印出对象的状态。
        //打印一个对象的时候,会自动调用该对象的toString()方法
		System.out.println(pet1);//等价于System.out.println(pet1.toStrng());
		System.out.println(pet2);
		System.out.println(pet3);
		System.out.println(pet4);
 
	}
 
}

3. OOP三大特性

3.1 封装

封装是指将某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法间接来实现对隐藏数据的操作和访问。

  • 将每个成员变量/方法用 private 修饰成私有成员不被外界修改从而提高程序安全性,
  • 可以为每个私有变量设置 set,get 方法以让其他类对私有成员进行操作

3.2 继承

特点:

  • 只支持单继承,但支持多层继承
  • 子类中所有的构造方法都会默认访问父类中无参构造方法(子类中构造方法第一条语句默认为 super() )
  • 子类继承父类数据,并且可能会用到父类数据,因此优先初始化父类

继承语法

public.....子类 extends 父类{
}

通过子类对象访问方法时: 先在子类找,若无则在父类中找,若无,则报错

3.3 多态

多态性是面向对象中最重要的概念,在Java中的体现:对象的多态性:父类的引用指向子类的对象

父类类型 变量名 = 子类对象;

例如:

Person p = new Student();
Object o = new Person();//Object类型的变量o,指向Person类型的对象
o = new Student(); //Object类型的变量o,指向Student类型的对象

Java 引用变量有两个类型:编译时类型运行时类型。编译时类型由 声明 该变量时使用的类型决定,运行时类型由 实际赋给该变量的对象 决定。

简称:编译时,看左边;运行时,看右边。

多态前提

继承或实现接口

无继承不重写

重写(编译看左,执行看右,若不重写则实现父类方法)

若想通过多态调用子类方法,则必须重写父类方法

父类引用指向子类对象/父接口指向子类对象

父类做方法参数值,父类做方法返回值类型
多态的意义
降低代码耦合性,提高代码扩展性

方法重载,重写体现多态,对象体现多态(重,难点)

父类引用指向子类对象(子类引用赋值给父类对象)

常见两种应用:

父类做方法参数类型

public class Person{
    private Pet pet;
    public void adopt(Pet pet) {//形参是父类类型,实参是子类对象
        this.pet = pet;
    }
    public void feed(){
        pet.eat();//pet实际引用的对象类型不同,执行的eat方法也不同
    }
}

public class TestPerson {
    public static void main(String[] args) {
        Person person = new Person();

        Dog dog = new Dog();
        dog.setNickname("小白");
        person.adopt(dog);//实参是dog子类对象,形参是父类Pet类型
        person.feed();

        Cat cat = new Cat();
        cat.setNickname("雪球");
        person.adopt(cat);//实参是cat子类对象,形参是父类Pet类型
        person.feed();
    }
}

父类做方法返回值类型

public class PetShop {
    //返回值类型是父类类型,实际返回的是子类对象
    public Pet sale(String type){
        switch (type){
            case "Dog":
                return new Dog();
            case "Cat":
                return new Cat();
        }
        return null;
    }
}

public class TestPetShop {
    public static void main(String[] args) {
        PetShop shop = new PetShop();

        Pet dog = shop.sale("Dog");
        dog.setNickname("小白");
        dog.eat();

        Pet cat = shop.sale("Cat");
        cat.setNickname("雪球");
        cat.eat();
    }
}

向上转型(自动类型转换)
//子 -> 父
Fu f=new zi();

能调用子类重写方法,父类本有方法,不能调用子类特有

向下转型(强制类型转换)

存在向上转型前提方可向下转型

//父 -> 子
Zi z=(Zi)f;

通过向下转型可以调用父类/子类方法/子类特有方法

到此为止,java面向对象你已经了解差不多了,后面还有接口,内部类,匿名类等正在等待你的阅读与关注!

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小为

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值