写在前面:
(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.可重用、可维护、安全性