笔记:对象与类

面向对象程序设计

  1. 面向对象程序设计简称OPP,面向对象的程序是有对象组成,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。许多对象来自标准库,还有一些自定义的;
  2. 结构化程序设计通过设计一系列过程(算法)来解决问题,首先确定如何操作数据,然后决定如何组织数据;面向对象将数据放在第一位,然后考虑操作数据的算法;
  3. 对于规模较小的问题,结构化程序设计比较理想,但面向大规模的问题,如实现一个包含2000个过程的问题,将其分解为100个类,每个类中包含20左右的方法将更容易理解和查找错误;
  4. (class):构造对象的模板,由类构造对象的过程称为创建类的实例(instance);类将数据和行为组合在一个包里并对使用者隐藏了数据的实现方式,实现了封装;对象中的数据称为实例域,操纵数据的过程称作方法(method);
  5. 在类中最常见的关系是:
    依赖(“use-a”):如果一个类的方法操纵另一个类的对象,就说一个类依赖另 一个类;
    聚合(“has-a”):一个类的对象包含另一个类的对象;
    继承(“is-a”):表示一般与特殊的关系,一个类不仅包含另一个类的方法,还拥有扩展的方法;

预定义类

对于已经定义好的类构造对象以及方法调用

Date类

import java.util.*;
public class Date01 {
	public static void main(String[] args) {
  	// TODO 自动生成的方法存根
  	//使用构造器构造新实例new Date()
 	//构造器名字与类名相同并且要在构造器前使用new操作符		
	System.out.println(new Date());//返回当前日期与时间
        Date deadline=new Date();
        //对象变量并没有实际包含一个对象而是引用了一个对象
        System.out.println(deadline);//对象变量deadline
        String s=deadline.toString();//调用类的方法
     }
}

LocalDate类

表示大家熟悉的日历表示法
java.util.Date和SimpleDateFormatter都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。
摘于:https://www.cnblogs.com/jaycekon/p/6179700.html

import java.time.LocalDate;
public class LocalDate01 {
	public static void main(String[] args) {
  // TODO 自动生成的方法存根
  //不使用构造器构造实例
  //使用静态工厂方法代表调用构造器
  System.out .println(LocalDate.now());
  LocalDate newYearsEve=LocalDate.of(1999, 12, 31);
  int year=newYearsEve.getYear();
  int month=newYearsEve.getMonthValue();
  int day=newYearsEve.getDayOfMonth();
  System.out.println("新年是:"+year+"-"+month+"-"+day);
  LocalDate aThousandDaysLater=newYearsEve.plusDays(1000);//得到1000天后的日期
  System.out.println(aThousandDaysLater); 
  }
}

更改器方法和访问器方法

import java.time.LocalDate;
public class LocalDate01 {
	public static void main(String[] args) {
	LocalDate newYearsEve=LocalDate.of(1999, 12, 31);
  	LocalDate aThousandDaysLater=newYearsEve.plusDays(1000);//plusDays方法会生成一个新的对象,然后将对象赋值给aThousandDaysLater,对象状态不变
  	System.out.println(aThousandDaysLater);//2002-09-26
  	
  	GregorianCalendar someDay=new GregorianCalendar(1999, 12, 31);
        someDay.add(Calendar.DAY_OF_MONTH, 1000);//更改器方法,someDay对象状态改变
        //只访问对象而不修改对象的方法称为访问器方法,如:getYear方法
        int year=someDay.get(Calendar.YEAR);
        int month=someDay.get(Calendar.MONTH);
        int day=someDay.get(Calendar.DAY_OF_MONTH);
        System.out.println("someDay是:"+year+"-"+month+"-"+day); 
     }
}

模拟日历

import java.time.DayOfWeek;
public class CalendarTest {
	public static void main(String[] args) {
  // TODO 自动生成的方法存根
  LocalDate date=LocalDate.now();
  int month=date.getMonthValue();
  int today=date.getDayOfMonth();
  date=date.minusDays(today-1);//将date设为这个月第一天
  DayOfWeek weekday=date.getDayOfWeek();//得到这一天为星期几
  int value=weekday.getValue();
  System.out.println("Mon Tue Wed Thu Fri Sat Sun");
  for(int i=1;i<value;i++) {
   System.out.print("    ");
  }
  while(date.getMonthValue()==month) {
   System.out.printf("%3d",date.getDayOfMonth());
   if(date.getDayOfMonth()==today) {
    System.out.print("*");//日期为当天用*表示
   }
   else 
    System.out.print(" ");
   date=date.plusDays(1);
   if(date.getDayOfWeek().getValue()==1) System.out.println();//为星期一就换行
  }
  if(date.getDayOfWeek().getValue()!=1) System.out.println();
  }
}

用户自定义的类

例题:

import java.time.LocalDate;
public class EmployeeTest {
  public static void main(String[] args) {
  	Employee[] staff=new Employee[3];
  	staff[0]=new Employee("Cral", 5600, 1999, 2, 20);
  	staff[1]=new Employee("Kral", 6600, 1998, 3, 15);
  	staff[2]=new Employee("Dral", 7600, 1997, 4, 10);
  	for(Employee e:staff) {
   		e.raiseSalary(10);
  	}
  	for(Employee e:staff) {
   		System.out.println("职工 "+e.getName()+" 在 "+e.getHireDay()+" 入职,当前工资为 "+e.getSalary());
  	}
 }
}
   class Employee{
     //实例域 field
 	private String name;
 	private double salary;
 	private LocalDate hireDay;
	//构造器 constructor
 	public Employee(String n,double s,int year,int month,int day) {
  		name=n;
  		salary=s;
		hireDay=LocalDate.of(year, month, day);
 	}
 	//四个方法 method
 	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=salary+raise;
 	}
}

详解

  1. 构造器与类同名,每个类可以有一个以上的构造器,构造器没有返回值,总伴随new操作符一起调用;
  2. 关键词private保证只有类自身的方法可以访问实例域,而其他类不能读写这些实例域,一般不提倡使用public修饰实例域;
  3. 对于 e.raiseSalary(10); 其中 e 称为隐式(implicit)参数,是出现在方法名前的Employee类对象;括号里面的10 称为显示(explicit)参数,是位于方法名后括号里面的值,同理double byPercent也是显示参数;关键字this为隐式参数,例如:
public void raiseSalary(double byPercent) {
   double raise=this.salary*byPercent/100;
   this.salary=this.salary+raise;
 }
}

4.私有方法:尽管大多数方法为公有的但是也可以将它设计为私有的;
5.final实例域:可以将实例域定义为final,必须确保在一个构造器中被赋值,并且在后面的操作中无法更改,final修饰符大都用于基本类型域或不可变类的域(例如String为不可变类而String Builder不是不可变类);

静态域与静态方法

  • 静态域:静态域也称为类域,每个类中只有一个定义为static的域,每一个对象有实例域的拷贝,静态域相当于是同一类的众多对象的唯一标识符,静态域属于类而不单独属于某一个对象;
  • 静态常量,例如:
    public class Math{
    . . .
    public static final double PI=3.14159265358979323846;
    . . .
    }
    中可以通过Math.PI来使用这个常量,而实例域只能通过类的对象来访问;
  • 静态方法:静态方法不能向对象实施操作,即没有隐式参数;静态方法是没有this参数的方法,不能使用实例域,但是可以访问自身的静态域;可以通过类名调用这个方法;在一个方法不需要访问对象状态或只需要访问静态域的时候可以选择使用静态域;
  • 工厂方法(factory method):例如LocalDate.of、LocalDate.now
    使用工厂方法原因:
    1.不希望构造器名字和类名一样 ;
    2.使用构造器时无法改变所构造的对象类型;
  • main方法是一种静态方法
  • 练习:
import java.time.LocalDate;
public class Statictest {	
	public static void main(String[] args) {
		Employee02[] staff=new Employee02[3];
  		staff[0]=new Employee02("Cral", 5600);
  		staff[1]=new Employee02("Kral", 6600);
  		staff[2]=new Employee02("Dral", 7600);
  		for(Employee02 e:staff) {
   			e.setId();
   			System.out.println("name="+e.getName()+",id="+e.getId()+",salary="+e.getSalary());
  		}
  		//静态方法
  		int n=Employee02.getNextId();
  		System.out.println("Next available id="+n);
 	}
} 
class Employee02{	
	//静态域
 	private static int nextId=1;
 
 	private String name;
 	private double salary;
 	private int id;
 
 	public Employee02(String n,double s) {
  		name=n;
  		salary=s;
  		id=0;
 	}
 	public String getName() {
  		return name;
 	}
 	public double getSalary() {
  		return salary;
 	}
 	public int getId() {
  		return id;
 	}
 	public void setId() {
  		id=nextId;
  		nextId++;
 	}
 	public static int getNextId() {
  		return nextId;
 	}
 	//每一个类可以有一个类方法,以下的main方法用于对类进行测试
 	public static void main(String[] args) {
  	Employee02 e=new Employee02("Harry",50000);
  	System.out.println("name="+e.getName()+",id="+e.getId()+",salary="+e.getSalary());
 	}
} 	

方法参数

  • Java程序设计语言总是采用按值调用,方法得到的是参数变量的拷贝,无法修改参数变量的内容;
  • 方法参数有两种类型:

基本数据类型(数字或布尔值)

public static void tripleValue(double  x){
 x=x*3;
}
double percent=10;
tripleValue(percent);
//先执行x=percent进行拷贝,x->30而percent->10;

对象引用

public static void tripleValue(Employee  x){
 x.raiseSalsry(200);
}
Employee e=new Employee(...); 
tripleValue(e);
//x首先初始化为e的拷贝,然后两者同时引用raiseSalary方法,所以e的薪资同时改变;

然而并不能因此认为Java是按引用调用,反例:

public static void swap(Employee  x,Employee  y){
	Employee  temp=x;
	x=y;
	y=temp;
}
......
Employee  a=new Employee(...);
Employee  b=new Employee(...);
swap(a,b);
//无法实现a,b交换,因为交换成功的是x,y这两个引用,最后x,y被舍弃,a,b依旧调用以前所引用的对象

总结:

  • 一个方法无法改变基本数据类型参数;
  • 一个方法可以改变对象参数的状态;
  • 一个方法无法让对象参数引用另一个新的对象。

对象构造

基本构造形式

  • 有些类可以有多个构造器(重载overloading);
  • 如果编写一个类的时候没有编写构造器,系统会提供一个无参数的构造器,构造器将所有实例域设置为默认值,但是如果编写的时候提供了至少一个构造器,但是没有提供无参构造器,则在构造对象的时候没有提供参数将视为不合法;

特殊构造形式

  • 调用另一个构造器:如果构造器的第一个语句形如this(…),表示将调用同一个类中的另一个构造器,例如:
public Employee(double s){
	//Employee(String s,double s);
	this("Employee #"+nextId,s);
	nextId++;
}
  • 初始化块:在一个类的声明中,可以包含多个代码块,只要构造对象,就会执行这些块;
  • 测试:
import java.time.LocalDate;
import java.util.*;
public class ConstructorTest {
	public static void main(String[] args) {
  		Employee03[] staff=new Employee03[3];
  		staff[0]=new Employee03("Cral", 5600);
  		staff[1]=new Employee03(6600);
  		staff[2]=new Employee03();
  		for(Employee03 e:staff) {
   		System.out.println("name= "+e.getName()+",id="+e.getId()+" salary= "+e.getSalary());
  		}
 	}
}
class Employee03{
	private static int nextId;
 	private int id;
 	private double salary;
	private String name="";
 	//静态初始化块
 	static {
  		Random generator=new Random();
  		nextId=generator.nextInt(10000);//生成0~9999之间的随机数
 	}
 	//对象初始化块
 	{
  		id=nextId;
  		nextId++;
 	}
 	//构造器重载
 	public Employee03(String n,double s){
  		name=n;
  		salary=s;
 	}
 	public Employee03(double s){
  		//Employee03(String s,double s);
  		this("Employee #"+nextId,s);
  		nextId++;
 	}
 	public Employee03(){
  		//无参构造器
 	}
 	public int getId() {
  		return id;
 	}
 	public String getName() {
  		return name;
 	}
 	public double getSalary() {
  		return salary;
 	}
}

--------全文参考《Java核心技术卷1》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开文档:每个资源包都附有详细的开文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开者也能逐步掌握项目开的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值