对象与类
类
java所有代码都位于某个类内部
java可以通过拓展(使继承)一个类来建立新的类。
事实上所有的类都来源于Object类(超类)
设计时应该先从设计类开始,然后向类中添加方法
例如
订单处理系统
-
商品(Ltem)
-
订单(Order)
-
送货地址(Shipping address)
-
物流(Transport)
-
付款(Payment)
-
账户(Account)
商品类传递一个商品变量给订单类,同时减少一个该商品数量 订单类调用付款类的相关方法,付款方法返回一个布尔值给订单以确定是支付成功或是取消订单 订单确认支付后,付款类调用账户类扣除相应的款项 订单确认支付后,订单类获取送货地址类并发送送货信息,由运输类送达 完成
代码如下
public class Ltem//商品类
{
public String ltem="Aria";
public int letmnum=40;
public int price=1000;
public String getLtem()
{
return ltem;
}
public int getLetmnum()
{
return letmnum;
}
public int getPrice()
{
return price;
}
public void buy(int num)
{
this.letmnum = letmnum-num;
}
}
//
public class Order//订单类
{
int num;
double price;
String address;
String accountname;
Ltem ltem=new Ltem();
public void order(int nums)
{
//this.num=ltem.getLetmnum();
if(nums>ltem.getLetmnum())
{
System.out.println("所售商品库存不足!");
System.exit(1);
}
else
{
Payment payment=new Payment();
if (payment.payment(nums,ltem.price)== false)
{
System.out.println("您的账户余额不足!");
System.exit(2);
}
else
{
ltem.buy(nums);
ShippingAddress shippingAddress=new ShippingAddress();
Account account=new Account();
this.address=shippingAddress.shippingAddress();
this.accountname=account.accountname;
Transport transport=new Transport();
transport.transport(this.accountname,ltem.ltem,nums,shippingAddress.address);
System.out.println("您的订单已完成,您的账户"+accountname+"余额为"+(account.balance-ltem.price*nums)+"¥\n感谢您的惠顾!");
}
}
}
}
public class Account//账户类
{
public double balance=10000;
public String accountname="GFFTD";
public Boolean getBalance(int num,double price)
{
//return (balance>=price) ? true:false;
if (balance>=price*num)
{
this.balance=this.balance-price*num;
return true;
}
else
{
return false;
}
}
}
public class Payment//付款类
{
int num;
double price;
Ltem ltem = new Ltem();
public boolean payment(int nums,double prices)
{
Account account=new Account();
return account.getBalance(nums,prices);
}
}
public class ShippingAddress//地址类
{
String address="太原理工大学明向校区";
public String shippingAddress()
{
return this.address;
}
}
public class Transport//物流类
{
public void transport(String accountname ,String ltemname,int ltemnum,String address)
{
System.out.println("您的账户"+accountname+"所购买的"+ltemnum+"件"+ltemname+"已经送达"+address);
}
}
public class text//测试类,调用Order类
{
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
//Ltem ltem=new Ltem();
System.out.println("输入购买的件数");
int num=scan.nextInt();
Order order=new Order();
order.order(num);
}
}
类间的关系
-
依赖
-
聚合
-
继承
依赖比较容易懂 聚合指的是A类中包含B类中部分对象 继承指的是
对象变量
使用对象前必须先构造对象
指定其初始状态
构造器
JAVA中需要使用构造器来构造新实例。
例
DAte date =new Date()
这个表达式构造了一个新对象。这个对象被初始化为当前的日期和时间
若果有需要的话,这个对象也可以传给一个方法
`System.out.println(new Date());`
也可以将一个方法应用于刚刚创建的对象上。Date类中有个toString()方法
String S=new Date().toString();
通常,希望构造的对象可以多次使用,而常常定义为Date变量中
Date birthday = new Date();
但是对象和对象变量间存在一个重要区别。如:Date deadline;deadline是一个对象变量他可以引用Date型对象,但是它不是个对象(实际此时也没有引用任何对象)。那么此时就不能将其用于任何变量上(如:S=deadline.toString();//会报错,因为deadline还没有引用任何对象)。
这种情况下就需要初始化deadline,为其引用一个已经存在的Date对象。
如:deadline=new Date();或:deadline=birthday(birthday此前初始化过)
注意:对象变量实际上没有包含一个变量,而仅仅是对对象的引用(refer)
LocalDate类
Date类通常用于表示时间点。LocalDate则用于表示日历表示法。
通常不要使用构造器来构造LocalDate类。应当使用静态工厂方法(factory method)
LocalDate.new();
当然也可以指定特定的日期
LocalDate.of(1999,11,18);
将其保存到一个构造对象中
LocalDate myBirthday = LocalDate.of(1999,11,18);
有了LocalDate对象后,可以调用以下方法:
myBirthday.getYear();//获取年份,以下省略
myBirthday.getMonthValue();
myBirthday.getDayOfMonth();
int year =myBirthday.getYear();
int month =myBirthday.getMonthValue();
int day =myBirthday.getDayOfMonth();
除此之外,日期还可以进行计算
plusDay方法
将会产生一个距离某天多少天的一个新的LoacalDate
LocalDate aThousandDaysLater=myBirthday.plusDays(1000);
int year =aThousandDaysLater.getYear();
int month =aThousandDaysLater.getMonthValue();
int day =aThousandDaysLater.getDayOfMonth();
例:打印当前月份的日历
要求,打印当前月份的日历,本日用后星号标记
给出几个所需的方法
- 获取本月初第一天:
date=date.minusDays(today-1);
或者(效果同上):date=LocalDate.of(year,month,1);
- 获取这一天是星期几:
DayOfWeek weekday=date.getDayOfWeek();
将这一天转换为一个int值:int value=weekday.getValue();
其中1=Monday …7=Sunday
完整代码如下
import java.time.DayOfWeek;
import java.time.LocalDate;
public class Caendars
{
public void newCa()
{
LocalDate date=LocalDate.now();
int year = date.getYear();
int month=date.getMonthValue();
int day=date.getDayOfMonth();
date =date.minusDays(day-1);//date=LocalDate.of(year,month,1);//这俩其实一样,都是将本月1号赋值给date
DayOfWeek weekday=date.getDayOfWeek();
int value=weekday.getValue();//1=Monday.....7=Sunday;
System.out.println("Sun Mon Tue Wed Thu Fri Sat");
for (int i=1;i<value+1;i++)
{
System.out.print("\t");
}
while (date.getMonthValue()==month)
{
System.out.printf("%3d",date.getDayOfMonth());
if (date.getDayOfMonth()==day)
{
System.out.print("*");
}
else
{
System.out.print(" ");
}
date=date.plusDays(1);
if (date.getDayOfWeek().getValue()==7)
{
System.out.println();
}
}
}
}
例::编写一个员工类
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;
import static com.sun.tools.attach.VirtualMachine.list;
public class text
{
public static void main(String[] args)
{
Emloyee [] staff=new Emloyee[3];
staff[0]=new Emloyee("Tom",10000,LocalDate.of(2010,1,30));
staff[1]=new Emloyee("Jerry",210000,LocalDate.of(2019,7,30));
staff[2]=new Emloyee("Sam",1210000,LocalDate.of(2008,7,30));
for (Emloyee s:staff)
{
System.out.print("name:"+s.getName()+"\t");
System.out.print("hireDay:"+s.getHireDay()+"\t");
System.out.print("Now Salary:"+s.getSalary()+"\t");
s.raiseSalary(5);
System.out.print("After Salary:"+s.getSalary());
System.out.println();
}
}
}
class Emloyee
{
private String name;
private double salary;
private LocalDate hireDay;
public Emloyee(String name,double salary,LocalDate hireDay)
{
this.name=name;
this.salary=salary;
this.hireDay=hireDay;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public LocalDate getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise=salary*byPercent/100;
salary+=raise;
}
}
访问包位置\类修饰符 | private | protected | public |
---|---|---|---|
本类 | 可见 | 可见 | 可见 |
同包其他类或子类 | 不可见 | 可见 | 可见 |
其他包的类或子类 | 不可见 | 不可见 | 可见 |
注: 父类的private方法和内部类,子类是不可见的,无法调用和继承
final 实例域
final关键字
private finalStringBuilder eva;
在Employee构造器中会初始化为:
eva=new StringBuilder();
final只限定对象变量引用,使得该对象不再指向其他对象。但是其实并不对对象做限定。对象本身依然可以进行更改。而对象变量不可改变。
static 静态域与静态方法
无论有多少个对象,每个静态域(变量或方法)有且仅有一个静态域(又名类域)。
加载类时优先加载静态域(static)
静态域又包括
静态常量
其实就是通用的 static修饰的常量。适用于比如PI这样的恒定常量。
静态方法
不能向对象试试操作的方法。如Math类的pow(x,n)方法
Math.pow(x,n)可以用于计算x的n次幂。运算时不必定义或使用任何Math对象。可以直接调用,也没有this参数
当然静态方法也可以通过创建类的对象,然后通过对象变量调用。但是这样往往容易混淆,而且由于需要初始化整个类,所以可能会造成额外的性能开支
通常以下两种情况推荐使用静态方法
-
一个方法不需要访问对象状态,其所需的所有参数都可以通过显示参数提供(即方法后括号内的变量,如Math.pow(x,n).x,就是其显示变量)
-
一个方法只需要访问类的静态域
工厂方法(factory method)
工厂方法特殊的点在于,一般不使用 变量名 = new 类名(); 的构造方式。
而是采用: 类名 变量名 = 类名.get方法名();
如:
DayOfWeek weekday=date.getDayOfWeek();
之所以不使用 new构造器。主要有以下两个原因:
-
无法命名构造器。 new方法要求其后的构造器必须和引用的类名同名。但是实际上经常需要构造器和类名不同名。
-
若使用构造器则无法改变所构造的对象的类型。
main方法
结构如下
public class Application
{
public static void main (String[] args)
{
}
}
main函数是一个静态的方法,启动程序时先从main函数启动,然后由main函数创建对象,进而启动其他所有所需方法
方法参数
参数传递一般分为两种。一种是按值调用,一种是按地址调用
Java中一般采用按值调用,调用的是值的拷贝
对象构造
重载
重载指的是 有相同的名字但是参数不同,便构成了重载
初始化
大多数类都会有一个构造函数,构造函数与类名同名即可
如果没有写明,那么系统就会提供一个无参构造函数
默认的构造函数会把所有的数值类型设置为默认值(0,null,false)
构造函数格式如下
public ClassName()
{
}