2.面向对象基础-01Java类和对象

写在前面:

(1)编程语言的发展(人越来越容易理解):

  机器语言

  汇编语言

  高级语言-面向过程

  高级语言-面向对象

(2)面向对象的特点:

  封装性

  继承性

  多态性

01Java类和对象

  对象:属性(静态特征、数据)和行为(动态特征、方法)

  类:具有相同属性的行为的对象的抽象

  java中,万物皆可对象

一、Java类

  组成:数据成员和方法成员

    -数据成员(成员数据、变量、属性、字段):类/对象的属性-静态

    -方法成员(成员方法、过程、函数):类/对象的操作-动态

  例子:product类

public class Product 
{
    //数据成员
    public String name;
    public double price;
    public int storage ;
    public double cost;//成本
    public double discount = 1;
    public double capital = 1000000;//总资金
    public double profit = 0;//利润
    //构造函数
    public Product(String name, double price, int storage,double cost) {
        this.name = name;
        this.price = price;
        this.storage = storage;
        this.cost = cost;
    }
    //方法成员
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getStorage() {
        return storage;
    }
    public void setStorage(int storage) {
        this.storage = storage;
    }
    public double getDiscount() {
        return discount;
    }
    public void setDiscount(double discount) {
        this.discount = discount;
    }
    public double getCost() {
        return cost;
    }
    public void setCost(double cost) {
        this.cost = cost;
    }
    public double getCapital() {
        return capital;
    }
    public void setCapital(double capital) {
        this.capital = capital;
    }
    public double getProfit() {
        return profit;
    }
    public void setProfit(double profit) {
        this.profit = profit;
    }
    
    public void purchase(int num)
    {
        this.storage -= num;
        double profit1 = num*(price-cost);
        profit += profit1;
        capital += profit1;
    }
    public void addStorage(int num)
    {
        capital -= num*cost;
        if(capital < 0)
        {
            System.out.println("破产了!!!!!!!!");
        }
        this.storage += num;
    }
    public void applyDiscount(double discount)
    {
        if(discount >= 1)
        {
            discount = 1;
        }
        this.price = price*discount;
    }
    public void printInfo()
    {
        System.out.println("name : "+name);
        System.out.println("price : "+price);
        System.out.println("storage : "+storage);
        System.out.println("capital : "+capital);
        System.out.println("profit : "+profit);
        
    }
    
}

Main函数

import java.util.Scanner;
public class Main 
{
    public static void main(String[] args)
    {
        Scanner s = new Scanner(System.in);
        System.out.println("请输入产品名:");
        String name = s.next();
        System.out.println("请输入价格:");
        double price = s.nextDouble();
        System.out.println("请输入库存:");
        int storage = s.nextInt();
        System.out.println("请输入成本价:");
        double cost = s.nextDouble();
        Product p = new Product(name,price,storage,cost);
        System.out.println("请输入折扣:");
        p.applyDiscount(s.nextDouble());
        p.printInfo();
        System.out.println("请输入购买量:");
        p.purchase(s.nextInt());
        p.printInfo();
        System.out.println("请输入进货量:");
        p.addStorage(s.nextInt());
        p.printInfo();
        s.close();
    }
}

 

二、对象

  类和对象的关系:类是对象的类型,对象是类的实例

    创建对象

    适用对象

(一)对象创建和使用

  1.使用new创建新的对象:类名 对象变量名 = new 类名([参数]);

  2.对象变量.成员变量:访问对象的成员变量

  3.对象变量.方法(实参列表):调用对象的方法

  4.类占用内存:基加成员的占用,Object成员只记引用

(二)访问权限控制

  1.对不同类之间进行类、类的属性(数据)、类的方法(函数)的访问进行权限控制

   一般情况下,方法为public,数据为private。方法提供了访问一个对象的数据的对外接口,体现了对数据的保护。

  2.类与对象

    (1)类(商品)

      定义了所有商品的属性和行为

      是一种类型,用来定义变量

      表示一种静态概念,不占用内存

    (2)对象(这件商品)

      表达具体的实体

      运行时占用内存(属性),进行信息交互(操作)

    (3)把数据和对数据的操作放在一起,形成类->封装

      封装性 是面向对象程序的三大特征之一

  3.Java引用变量

    引用类型:java中除了基本类型以外的变量类型都是引用类型

    作用:通过引用操作对象,对象的管理者

      Product p = new Product();

     p:对象变量(引用)

     

     对象变量为空:null

  4.Java内存空间分配

    

   (1)方法执行有其内存栈,所有本地变量(包括形参)按顺序压入栈中(先进后出)

    -方法执行结束时其内存栈也将自然摧毁

   (2)创建对象时,该对象被保存在堆(运行时数据区)中,以便反复利用(创建对象成本较大)

    ①堆内存中的对象不会随方法的结束而摧毁(即使方法结束后,该对象还可能被引用)

    ②当对象还没有被引用时,系统会在合适的时候收回它

 5.时间类

public class MyTime 
{
    public int hour;
    public int minute;
    public int second;
    public MyTime(int hour, int minute, int second) 
    {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }
    public int getHour() {
        return hour;
    }
    public void setHour(int hour) {
        this.hour = hour;
    }
    public int getMinute() {
        return minute;
    }
    public void setMinute(int minute) {
        this.minute = minute;
    }
    public int getSecond() {
        return second;
    }
    public void setSecond(int second) {
        this.second = second;
    }
    
    public void before(MyTime t)
    {
        this.hour -= t.hour;
        this.minute -= t.minute;
        this.second -= t.second;
    }
    public void after(MyTime t)
    {
        this.hour += t.hour;
        this.minute += t.minute;
        this.second += t.second;
    }
    
    public void print()
    {
        System.out.printf("%02d:",this.hour);
        System.out.printf("%02d:",this.minute);
        System.out.printf("%02d",this.second);
    }
    
}

Main函数

import java.util.*;
public class Main 
{
    public static void main(String[] args) 
    {
        Scanner s = new Scanner(System.in);
        int hour = s.nextInt();
        int munite = s.nextInt();
        int second = s.nextInt();
        MyTime mt = new MyTime(hour,munite,second);
        mt.print();
        int hour1 = s.nextInt();
        int munite1 = s.nextInt();
        int second1 = s.nextInt();
        MyTime mt1 = new MyTime(hour1,munite1,second1);
        mt.before(mt1);
        mt.print();
        int hour2 = s.nextInt();
        int munite2 = s.nextInt();
        int second2 = s.nextInt();
        MyTime mt2 = new MyTime(hour2,munite2,second2);
        mt.after(mt2);
        mt.print();
        s.close();
    }
}

6.思考总结

思考

(1)Java中的值传递方式:JAVA中没有引用传递, 全部是按值调用

  ①函数为什么能修改真实的对象呢?这不是引用传递的特征吗?

      引用传递指针时, 连函数操作的指针都是原来的指针,比如C++传入对象时直接用传入的指针操作

      而JAVA的引用传进函数时 , 会复制一个引用与实参指向同一对象的引用, 操作的不是同一个引用,

    详见:https://blog.csdn.net/q5706503/article/details/82910428

(2)Java中对象的赋值是深拷贝还是浅拷贝

    详见:https://blog.csdn.net/liutaiyi8/article/details/108980650

(3)Java中对象的比较,如”==“比较的是对象的内存地址

总结

(1)引用类型变量存放在栈内存中;对象通过new产生,位于堆内存

(2)同一个类的每个对象占用不同的成员变量存储空间,每个成员变量在不同的对象中可以有不同的值(静态变量除外)

(3)方法仅一份,存放在代码区,执行时再分配内存。同一类的每个对象共享该类的代码。

三、Java类的生命周期

(一)构造方法

  1.也叫构造函数,用于初始化对象(使用new构造)

  2.特点:不能指定返回值类型;名字必须与类名一样;

  3.当不提供构造方法时,编译器提供默认构造方法;当提供了构造方法时,不再提供默认构造方法。

(二)显式初始化

  定义:在定义成员属性的时候就给定初值

(三)构造和初始化对象顺序

  new初始化对象的顺序

  1.申请内存空间,微信对象分配空间并初始化,所有基本数据类型数据设置成了默认值(如整数类型是0,布尔类型为false),而引用类型为null;

  2.执行显式初始化

  3.执行构造方法

  4.将对该对象的引用赋值给引用变量

(四)Java垃圾回收器

  Java不需要程序员直接控制内存回收,程序的内存分配和回收是jre在后台自动进行,jre负责回收不再使用的内存,这种机制被称为垃圾回收。

  程序员只需要申请空间构造对象(new),不需要释放空间销毁对象(delete in c++)

四、this引用

  (一)在类的方法定义中,使用this关键字代表使用该方法对象的引用,其值是当前对象的引用。

  (二)通过this来区分同一个类的不同对象对相同函数的调用:

    1.this来区分成员变量和本地变量

 public Product(String name, double price, int storage,double cost) {
        this.name = name;
        this.price = price;
        this.storage = storage;
        this.cost = cost;
    }

     2.用this在构造方法中调用其他构造方法

public Product()
{
    this("",0,0,0);
    //只出现一次,位于第一行,只在构造函数里
}

五、static变量

  (一)类变量-static变量(静态变量)

    1.不属于任何对象,属于类的变量

    2.可通过类名.静态变量 访问

    3.可通过变量名.静态变量 访问(实际也是通过变量得到它的类)

    4.可被静态函数或者成员函数访问

  (二)类函数-static函数

    -不可访问成员函数,但可被成员函数访问

  (三)实例:显示时间的时钟,模拟时钟运行

import java.util.*;
/*
 * 方法1:类似Mytime
        包含时、分、秒
        能够运行run,分别检测各个字段是否产生进位
    有什么缺点,有什么更好的设计方法?
        难以扩展
        时、分、秒的数据和行为类似
    方法2:构造类Field和Clock
        Field用来表示某个字段
        Clock用来协调三个字段

 */
public class Main
{
    public static void main(String[] args) 
    {
      Clock c = new Clock();
      c.run();
    }
}
class Field 
{
      int value;
      int limit;
      public Field(int value, int limit){
        this.limit = limit;
        this.value = value;
      }
      public int getValue() {
        return value;
      }
      public boolean increase() 
      {
          value++;
          if (value >= limit) 
          {
              value = 0;
              return true;
          } 
          else 
          {
                return false;
          }
      }
    }
class Clock 
{
      Field hour = new Field(0,24);
      Field minute = new Field(0,60);
      Field second = new Field(0,60);
      public void run() 
      {
        while (true) 
        {
            boolean s = second.increase();
            if (s) 
            {
                boolean m = minute.increase();
                if (m) 
                {
                    hour.increase();
                }
            }
            System.out.printf("%02d:%02d:%02d
",
                                hour.getValue(),
                                minute.getValue(),
                                second.getValue());
        }
      }
}

 修改Field,使得Field之间可以关联:

import java.util.*;
/*
 * 改进,使Field之间可以关联

 */
public class Main
{
    public static void main(String[] args) 
    {
      Clock c = new Clock();
      c.run();
    }
}
class Field 
{
    private int value=0;
    private int limit;
    private Field higherField;
    
    public Field(int limit, Field higherField) 
    {
        this.limit = limit;
        this.higherField = higherField;
    }
    public Field(int limit) 
    { 
        this.limit = limit; 
    }
    public int getValue() 
    {
        return value; 
    }
    public void increase() 
    {
        value ++;
        if (value==limit) 
        {
            value = 0;
            if (higherField!=null)   
            {
                higherField.increase();
            }
        }
    }
}

class Clock 
{
    private Field hour;
    private Field minute;
    private Field second;
    
    public Clock() 
    {
        hour = new Field(24);
        minute = new Field(60,hour);
        second = new Field(60,minute);
    }
    public void run() 
    {
        while(true) 
        {
            second.increase();
            System.out.printf("%02d:%02d:%02d
",
                    hour.getValue(),
                    minute.getValue(),
                    second.getValue());
        }
    }
}

六、封装性怎么理解

  1.封装对象的属性和方法,形成一个不可分割的独立单位

    -类、类的成员属性和成员方法

  2.信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界,仅提供公共访问方式,保留有限的对外接口

    -类的权限修饰

  3.封装原则:

    -将不需要对外提供的内容都隐藏起来

    -把属性都隐藏,提供公共方法对其访问

  4.可重用、可维护、安全性

原文地址:https://www.cnblogs.com/Chenury/p/14946633.html