美文网首页
Day3—面向对象(对象创建于使用、属性、方法、构造器、封装)

Day3—面向对象(对象创建于使用、属性、方法、构造器、封装)

作者: OmewSPG | 来源:发表于2024-03-27 10:56 被阅读0次

概述

面向对象的三大特征
  • 封装 (Encapsulation)
  • 继承 (Inheritance)
  • 多态 (Polymorphism)
面向对象的思想概述

类(Class)和对象(Object)是面向对象的核心概念。

  • 类是对一类事物的描述,是抽象的、概念上的定义
  • 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)

可以理解为:类 = 抽象概念的人;对象 = 实实在在的某个人
面向对象程序设计的重点是类的设计;而类的设计,其实就是类的成员的设计。

java类

类的语法格式
修饰符  class  类名 {

    属性声明;
    方法声明;

}
类的成员构成
  • 属性
  • 构造器
  • 方法
  • 代码块
  • 内部类
类的成员构成

对象创建和使用

要想创建一个对象并且使用,首先要进行类的创建:

// 类的创建
class Person{
    // 属性
    String name;
    int age;

    // 方法
    public void grown(){
        age++;
    }

    public void greeting(){
        System.out.println("Domo, my name is "+ name +", nice to meet you!");
    }

}

有了类之后,便可以通过类名创建对象,并且通过" . "的方式来访问对象中的属性和方法:

    public static void main(String[] args) {
        
        // 创建对象
        Person p1 = new Person();

        // 调用属性
        p1.name = "Kana";
        p1.age = 14;
        System.out.println(p1.name);
        System.out.println(p1.age);
        
        // 调用方法
        p1.greeting();    // Domo, my name is Kana, nice to meet you!
        p1.grown();
        System.out.println(p1.age);   // 15
    }

完成一个对象创建后,系统会给对象的属性赋予默认的初始值;同时,对象之间的直接复制,本质上是将两个对象指向了同一个地址值。这点跟数组的情况非常类似:

        // 对象内属性的默认初始化值
        Person p2 = new Person();
        System.out.println(p2.name);   // null
        System.out.println(p2.age);   // 0

        // 对象复制(类似数组)
        Person p3 = new Person();
        p3 = p1;
        p3.name = "Yuki";
        System.out.println(p1.name);   // Yuki

以上代码的内存解析图如下:


内存解析图
匿名对象

可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。

new Person().shout(); 

使用情况:

  • 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
  • 匿名对象可作为实参传递给一个方法进行调用。

比如,先声明一个Phone的类:

class Phone{
    // 属性
    double price;
    
    // 方法
    public void sendEmail(){
        System.out.println("Send E-mail...");
    }
    
    public void playGame(){
        System.out.println("Game Start!");
    }
    
    public void showPrice(){
        System.out.println(price);
    }
}

通过匿名对象的形式,调用其方法:

// 匿名对象
// 每一个匿名对象,都会是一个单独的实例
new Phone().playGame();
new Phone().price = 1999;
new Phone().showPrice();   // 0.0

这里需要注意,每一个匿名对象,都是一个单独的实例;即便上述代码通过调用匿名对象方法对其price属性进行赋值,但是通过调用匿名对象方法打印出来的price值依旧是0.0,这说明两次调用方法的不是同一个实例。

接着,再声明PhoneMall的类,它没有属性值,仅有一个通过Phone创建的实例作为参数、调用其方法的方法:

class PhoneMall{
    public void showPhone(Phone phone,double price){
        phone.price = price;
        System.out.println(phone.price);
        phone.sendEmail();
        phone.playGame();
    }
}

Phone的匿名对象作为实参,传递给方法进行调用。以下例子是通过这样的操作完成对匿名对象的price属性进行修改:

// 匿名对象的使用
PhoneMall mall = new PhoneMall();
mall.showPhone(new Phone(),2999);   // 作为形参进行值传递,调用方法或者更改属性

类的属性

属性是类的成员之一,同时作为类的变量存在

当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值,这点与数组十分类似:


对象属性的初始化值
变量(补充)

变量分为局部变量和全局变量(成员变量),类的属性就属于全局变量的一种;它们之间详细的分类和区别如下:


变量

结合之前类的属性、以及方法的形参进行比较,局部变量和全局变量的区别如下:


局部变量与全局变量

类的方法

  • 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。
  • 将功能封装为方法的目的是:可以实现代码重用,简化代码。
  • Java里的方法不能独立存在,所有的方法必须定义在类里。
class Customer{

    // 属性
    String name;
    int age;


    // 方法
    public void intro(){   // 无形参、无返回值
        System.out.println("Hello, nice to meet you");
    }

    public void years(int year){   // 有形参、无返回值
        age += year;
        return;    // 可省略,表示结束此方法
    }

    public String getName(){     // 无形参、有返回值
        return name;
    } 

    public String getNation(String nation, String district){    // 有形参(形参列表)、有返回值
        return nation + "," +district;
    }
}

方法的定义形式跟其返回值类型和参数有直接关系,在通过对象调用方法时,也需要根据返回值类型和参数注意其格式:

        // 创建实例
        Customer cus1 = new Customer();

        cus1.name = "Tom";
        cus1.age = 24;

        cus1.intro();
        cus1.years(10);
        System.out.println(cus1.age);    //  34
        System.out.println(cus1.getName());
        System.out.println("I am coming from " + cus1.getNation("China","Chongqing"));

注意:

  • 方法被调用一次,就会执行一次。
  • 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
  • 定义方法时,方法的结果应该返回给调用者,交由调用者处理。
  • 方法中只能调用方法或属性,不可以在方法内部定义方法。
  • 方法结束后,方法中定义的局部变量会被释放掉。
方法重载
  1. 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
  2. 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。

以下三个方法彼此之间构成重载:

    public int getSum(int i,int j){
        return (i + j);
    }
    
    public double getSum(double i,double j){
        return (i + j);
    }
    
    public String getSum(String i,String j){
        return (i + j);
    }
    
//  public int getSum(int i,int j){     // 报错
//      return 0;   
//  }
可变个数的形参

JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。

    public void show(int i){
        System.out.println(i);
    }
    
    public void show(String i){
        System.out.println(i);
    }
    
    public void show(String ...strings){   // 未指定参数数量
        String str = "";
        for(int i = 0; i < strings.length; i++){
            str += strings[i];
        }
        System.out.println(str);
    }
    
//  public void show(String[] strings){    // 本质上是数组形式
//  }

可变形参方法与其他同名方法之间构成重载。

值传递机制
  • 若参数是基本数据类型,实参赋给形参的是实参真实存储的数据值
  • 若参数是引用数据类型,实参赋给形参的是实参存储数据的地址值

比如以下类中,第一个方法的形参为基本数据类型,第二个方法的形参为引用数据类型,它们同样是执行交换数据的功能:

class Object{
    // 属性
    int m;
    int n;
    
    // 方法
    public void swap(int m ,int n){
        int temp = m;
        m = n; 
        n = temp;
    }
    
    public void swap(Object obj){
        int temp = obj.m;
        obj.m = obj.n; 
        obj.n = temp;
    }   
}
        // 若参数是基本数据类型,实参赋给形参的是实参真实存储的数据值
        int m = 10;
        int n = 20;
        Object obj = new Object();
        obj.swap(m,n);
        System.out.println("m = "+ m +";n = " + n);   //  m = 10;n = 20
         
        
        // 若参数是引用数据类型,实参赋给形参的是实参存储数据的地址值
        obj.m = 10;
        obj.n = 20;
        obj.swap(obj);
        System.out.println("obj.m = "+ obj.m +";obj.n = " + obj.n);   //  obj.m = 20; obj.n = 10

然而两个方法的执行结果却大相径庭,采用基本数据类型作为形参的方法,其实参传递给形参后进行交换,完全不会影响到对象内的属性值;而采用引用数据类型作为形参的方法,因为直接交换的地址值,所以其指向的对象也会发生实质性的交换。

递归方法

递归方法:一个方法体内调用它自身

  • 1、方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
  • 2、递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

比如:

    // 利用递归累积求和
    public int getSum(int n){
        if(n == 1){
            return 1;
        }else{
            return n + getSum(n-1);
        }
    }

当调用getSum(100)时,因为内部存在递归方法,就会调用 getSum(99) ;同理,当调用 getSum(99) 时,就会调用 getSum(98) ... ... 以此类推,最终总会调用 getSum(1) = 1 这个已知的条件,从而按原来相反的顺序返回 getSum(100) 的值。

封装与隐藏

隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想

比如,声明一个Animal类,并使其legs属性为私有的,如需通过对象对该属性使用,则需要在类中声明访问私有属性的方法 getXxx() 和 setXxx() 。

class Animal{
    // 属性
    String name;
    int age;
    private int legs;   // 腿的个数
    
    // 方法
    // 属性的设置与获取
    public void setLegs(int l){
        if(l >= 0 && l % 2 ==0){
            legs = l;
        }else{
            legs = 0;
        }
    }
    
    public int getLegs(){
        return legs;
    }
    
    // 其它函数
    public void eat(){
        System.out.println("eating...");
    }
    
    public void show(){
        System.out.println("name:"+ name +"  age:"+ age +"  legs:"+ legs);
    }
}

创建Animal类的实例后,无法再用 “.” 的方式访问其私有属性。而应该使用事先声明好的 getXxx() 和 setXxx() 方法:

        Animal a = new Animal();
        a.name = "dog";
        a.age = 2;
//      a.legs = 4;    // 属性不可见/隐藏,不可直接调用
        a.setLegs(4);
        System.out.println(a.getLegs());
        a.show();
权限修饰符

Java权限修饰符public、protected、(缺省)、private置于类的成员定义前,用来限定对象对该类成员的访问权限。


权限修饰符

类的构造器

类的构造器用来创建对象;并给对象进行初始化。

比如声明一个Student类:

class Student{
    // 属性
    private String name;
    private int age;
    
    // 构造器
    public Student(){    // 系统提供的默认构造器
        
    }
    
    public Student(String n){
        name = n;
    }
    
    public Student(String n, int a){
        name = n;
        age = a;
    }
    
    // 方法
    public void show(){
        System.out.println("Name:"+ name +"  Age:" + age);
    }
}
  1. 如没有事先显示定义构造器,则系统默认提供一个空参数的够造器
  2. 一旦显示定义了构造器,系统就不会提供默认构造器
  3. 一个类中可以定义多个构造器,彼此构成重载
        Student stu = new Student();
        stu.show();
        
        Student stu1 = new Student("Kana", 16);
        stu1.show();
构造器特征
  • 它具有与类相同的名称
  • 它不声明返回值类型。(与声明为void不同)
  • 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值

关键字(this、package、import)

this

当this在方法内部使用,即这个方法所属对象的引用;
当this在构造器内部使用,表示该构造器正在初始化的对象。

当在方法内需要用到调用该方法的对象时,就用this。
具体的:我们可以用this来区分属性和局部变量。
比如:this.name = name;

class Person{
    // 属性
    private String name;
    private int age;

    // 方法
    public void setName(String name){
        this.name = name;
    }
    
    public void setAge(int age){
        this.age = age;
    }
    
    public String getName(){
        return this.name;
    }
    
    public int getAge(){
        return this.age;
    }
    
    public void show(){
        System.out.println("Name:"+this.getName()+"  Age:"+this.getAge());
    }
}

this修饰构造器:

// 构造器
    // this修饰/调用构造器
    public Person(){
        // 假设对象初始化,必须输出以下字段
        System.out.println("this is an important sentence!");
    }
    
    public Person(String name){
        this();
        this.name = name;
    }
    
    public Person(int age){
        this();
        this.age = age;
    }
    
    public Person(String name,int age){
        this(age);      // 通过this(field)来调用其他指定的构造器
        this.name = name;
    }
package

package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。

package project.java;

系统文件夹会创建对应的路径:


系统文件夹
import

为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*)。import语句告诉编译器到哪里去寻找类。

package practice.java;

import project.java.*;

public class Test {
    public static void main(String[] args) {
        CustomerView cs = new CustomerView();
        cs.enterMainMenu();
    }
}

通过import,在当前包(practice)中导入另一个包(project)的项目工程。

相关文章

  • 20170610基础知识-面向对象

    Object Oriented ProgrammingOOP:面向对象,使用对象、类、继承、封装、属性、方法、扩展...

  • 面向对象1

    java面向对象的3条主线 1.java类及类的成员、属性、方法、构造器、代码块、内部类2.面向对象三大特征:封装...

  • TypeScript面向对象

    TypeScript面向对象 readonly 单层修饰只读属性。 构造器 构造方法。 方法 Getters/Se...

  • day3_面向对象(上)

    面向对象的三条主要线索: Java类以及类的成员:属性、方法、构造器、代码块和内部结构 面向对象的三大特征:封装性...

  • 创建js对象

    1、对象 2、创建对象的方法 3、遍历对象属性:for...in... 4、使用字面量创建对象 5、使用构造函数创...

  • 2019-11-27

    1.js 对象属性 2.js 对象方法 3.对象访问器 4.对象构造器 5.对象构造器加属性 6.对象方法 7.j...

  • Java基础-面向对象

    4.面向对象 属性+方法变成一个类 Java面向对象学习三条主线:1.Java类及类的成员:属性,方法,构造器;代...

  • 面向对象编程

    1.什么是面向对象编程 面向对象是对面向过程的高度封装,把所有的属性都放在构造函数内,把方法都放在原型里面。 2....

  • javase part4 - 面向对象

    Object is everything. 面向对象几大概念:(封装,继承,多态) (类,对象,属性,方法) 封装...

  • 2-JavaObjectOriented

    Java面向对象设计 类与对象、封装、构造方法 类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物...

网友评论

      本文标题:Day3—面向对象(对象创建于使用、属性、方法、构造器、封装)

      本文链接:https://www.haomeiwen.com/subject/ktkltjtx.html