黑马程序员——类与对象

------- android培训java培训、期待与您交流! ----------

一、概述

(一)类

是构造对象的模板

由类构造对象的过程称为:创建类的实例(对象)

封装:将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。关键:本类方法不能直接访问他类实例域。

 

类之间的关系:

依赖 uses-a:A类操作B类对象,耦合度高

聚合 has-a:A类对象包含B类对象

继承 is-a:A类是B类的扩展

 

(二)对象

实例域:对象中的数据

对象的状态:每个特定的对象都有一组特定的实例域值

方法:操作数据的过程

 

对象的三个特征

对象的行为:用可调用的方法定义(方法)

对象的状态:描述当前特征的信息。状态的改变必须通过调用方法实现(域)

对象的标识:每个对象唯一的身份(地址,hashcode)

 

二、使用预定义的类

(一)对象与对象变量

new Date()在堆内存中创建了一个新的对象

声明一个Date d的引用型变量类似于指针)指向new Date()创建的新的对象,则d是这个对象的对象变量

一个对象变量并没有实际包含一个对象,仅仅是引用一个对象。(可以有多个对象变量指向同一个对象)

 

使用变量:

1.构造对象

2.指定初始状态

3.对对象应用方法

(二)类方法

         构造器ctor:构造新的实例,初始化对象。通常希望构造的对象可以多次使用,所以将对象放在对象变量中。

         更改器setter:对实例域做出修改的方法    

 访问器getter:仅访问实例域而不进行修改的方法

/**
在控制台中打印出台历,要求给今天的日期后加*
Sun Mon Tue Wed Thu Fri Sat
                     1   2 
 3   4   5   6   7   8   9 
10  11  12  13  14  15  16 
17  18  19  20  21  22  23*
24  25  26  27  28  29  30 
31
需求:
1日历需要知道当前时区定义第一天是周几,比如周日还是周一
GregorianCalendar: getFirstDayOfWeek()
int firstWeekDay=day.getFirstDayOfWeek();

2第一天需要在其所在的星期的位置上,1日之前有多少空格需要确认
	通过day.set(Calendar.DAY_OF_MONTH,1)将日期调整到1号,再获取1号的星期int weekday=day.get(Calendar.DAY_OF_WEEK);
	计算1号的星期离每周第一天差多少天->得到需要空多少格:
		int diff=0;
		while(firstWeekDay+diff<weekday){
			++diff;
		}

3需要将星期排序的缩写打印在第一行
a)DateFormatSymbols中的getShortWeekdays可以返回一周的缩写字符的数组weekName
b)然后将日期调整到本月1号所在那个星期的第一天
day.add(Calendar.DAY_OF_YEAR, -(diff));
c)然后返回第一天的星期,再通过weekName索引得到当日的星期的缩写,通过7次循环得到一周的字符缩写
循环中日期的增加通过day.add(Calendar.DAY_OF_YEAR, 1);实现

4计算本月有多少天
在28日建立一个day的副本,从28号起,每增加一日就和副本进行比较月份,月份不同说明已到下个月,通过差得到一个月的天数

5空格数+当月天数就得到一共需要循环多少次,然后在循环中判断是空格还是1-9日,还是10日以上,分别打印不同的信息。
同时判断本次循环的日期是否是本日,如果是本日则加*
*/
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
public class TableCalendar {
	public static void main(String[] args) {
		StringBuilder sb=new StringBuilder();
		
		//now
		GregorianCalendar day=new GregorianCalendar();		
		//now in day & month	
		int today=day.get(Calendar.DAY_OF_MONTH);
		int month=day.get(Calendar.MONTH);
		//the first week day of the local timezone
		int firstWeekDay=day.getFirstDayOfWeek();
		
		//set day to the 1st day of this month
		day.set(Calendar.DAY_OF_MONTH,1);
		int weekday=day.get(Calendar.DAY_OF_WEEK);

		//get how many blank need
		int diff=0;
		while(weekday>firstWeekDay+diff){
			++diff;
		}
		
		//sort the order : weekdays in string  
		int cnt=0;
		String[] weekName=new DateFormatSymbols(Locale.ENGLISH).getShortWeekdays();
		day.add(Calendar.DAY_OF_YEAR, -(diff));//get the first "blank" day's weekday
		cnt=day.get(Calendar.DAY_OF_WEEK);
		
		//print the weekday String title
		for(int i=0;i<7;++i){
			//System.out.println(weekName[(firstWeekDay+i)%7]);
			sb.append(weekName[cnt]+" ");
			day.add(Calendar.DAY_OF_YEAR, 1);
			cnt=day.get(Calendar.DAY_OF_WEEK);
		}
		sb.delete(sb.length()-1, sb.length()).append("\r\n");
		
		//cnt a month have how many days
		GregorianCalendar day2=new GregorianCalendar();
		day.set(Calendar.DAY_OF_MONTH,28);
		day2.set(Calendar.DAY_OF_MONTH,28);
		int monthLen=27;
		while(day.get(Calendar.MONTH)==day2.get(Calendar.MONTH)){
			day2.add(Calendar.DAY_OF_YEAR, 1);
			++monthLen;			
		}	
		//System.out.println(diff+" "+monthLen);

		//print the month		
		int total=monthLen+diff;
		int cntDays=0;
		for(int i=1;i<=total;++i){			
			//blank
			if(i<=diff){
				sb.append("  ");
			//1-9
			}else if(i>diff&&i<=diff+9){
				sb.append(" "+(++cntDays));				
			}else{
				sb.append(++cntDays);		
			}
			
			
			//mark today
			if(cntDays==today){
				sb.append("* ");
			//skip the last day
			}else if(cntDays==monthLen){
				
			}else{
				sb.append("  ");	
			}			
			//newLine
			if(0==i%7){
				//sb.append("\r\n");
				sb.delete(sb.length()-1, sb.length()).append("\r\n");
			}			
		}
		System.out.println(sb);		
	}
}


三、使用自定义类

 class ClassName{

         field1

         field2

 

         ctor1

         ctor2

        

         method1

         method2

         getter

         setter

一个源文件只能有一个public类,源文件名必须与public类的类名相同

 

多源文件的使用

将类的代码单独放置在一个源文件中。

将测试/使用代码放在另一个源文件中。

 

编译时编译测试代码的源文件即可,当编译器发现使用了某个类会自动搜索其class文件,如果没有则会搜索和编译类的源文件;如果有class文件,但是源文件版本较新,编译器会自动重新编译。

//test.java Seller类虽然不是public,但是仍然可以用,默认权限包内可见
public class test {
	public static void main(String[] args) {
		Costumer c=new Costumer();
		Seller s=new Seller("aaaa");
		System.out.println(s);
	}
}
//Costumer.java
public class Costumer {
	
}
class Seller {
	private String name;
	public Seller(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public String toString() {
		return "Seller [name=" + name + "]";
	}
}

(一)构造器

ctor总是伴随new操作符的执行被调用,不能对已存在的对象使用ctor(object.ClassName()是错误的)

特点

1)ctor与类同名

2)每个类可以有多个ctor

3)ctor的参数个数不限

4)ctor没有返回值

5)总伴随new使用

(二)类方法

类的方法通常有两种参数:

隐式参数:出现在方法名前的类对象

显示参数:方法名后的括号中的参数

 

在每一个方法内部,关键字this表示隐式参数,这样可以将实例域与局部变量明显地区分开

(三)封装

获取/设置实例域的值

1一个私有的数据域

2一个公有的域访问器

3一个公有的域更改器

封装优点:

1可以改变内部实现。不影响其他方法

2更改器方法可以进行错误检查

 

不要编写返回引用可变对象的访问器方法,如果需要返回一个可变对象的引用,应先使用克隆方法(clone()),返回对应可变数据域的一个拷贝。

public Date getDate(){

         returnthis.day.clone();

}

(四)基于类的访问权限

基于类的访问权限:一个方法可以访问所属类的所有对象的私有数据。

 

final实例域:必须在ctor中设置这个final域的值,并在之后,无法再对其进行修改

final修饰符大多应用于基本类型域或者不可变类(类的每个方法都不会改变其对象)的域。

 

对可变对象使用final并不能保证对象内容不被修改,只能保证引用不变

private final Date day;//仅仅意味着day这个引用的指向在ctor后不可改变,但是指向的对象的内部的实例域仍然可以通过更改器修改。 

四、静态域和静态方法

(一)静态域

静态域:类域,属于类不属于任何独立的对象

         实例域:每个对象独立

         静态域:所有同类对象所共有

(二)静态常量

静态常量:[public] static final

         System.out就是静态常量。不能更改out。但是可以通过setOut()置为其他流。(setOut是本地方法,不是java语言实现的。所以可以绕过final)

(三)静态方法

静态方法:不能向对象实施操作的方法。可以认为静态方法没有this参数。

         因为静态方法不能操作对象,所以不能在静态方法中访问实例域。但是静态方法可以访问本类的静态域。

         可以使用对象调用静态方法,但是容易让人觉得混乱,应当使用类名调用静态方法

使用静态方法的情况

         1.不需要访问自身对象的状态,其所需参数都是显示参数提供

         2.需要访问静态域

(四)工厂方法

工厂方法:通过静态方法产生不同类型的返回对象。

         NumberFormatcurrenyFomatter=NumberFormat.getCurrencyInstance();

         NumberFormatpercentFomtter=NumberFormat.getPercentInstance();

         doublex=0.1;

         System.out.println(currencyFormatter.format(x));

System.out.println(percentFormatter.format(x));

(五)main方法

每一个类可以有一个main方法,(因为是静态方法,所以不需要对象,可以在启动时就运行。)每个类设置main()可以用于对类进行单元测试。

         运行时java ClassName则调用类内的main进行单元测试;运行时java AppName则调用程序的main方法运行程序。

五、对象构造

重载:相同的方法名,不同的参数列表

         方法的签名方法名+参数类,返回类型不是签名的组成部分e.g. indexOf(int)

 

调用构造器后的具体处理步骤

1所有数据域被初始化为默认值(0,false,null)(即是对域赋值为这些默认值)

2按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块(按照顺序执行,比如显示的域值初始化,初始化块)

3若构造器第一行调用了其他构造器,则执行第二个构造器主体(调用this()/super())

4执行这个构造器的主体(执行这个ctor内的代码)

 

 

1st默认域初始化:域的值将被初始化为0,false,null

 

2nd显示域初始化(实例域初始化instance field initialization):在类定义中,直接将一个值赋给任何域,比如:

         privateString name=”Alex”;

除了直接赋值。还可以调用方法:

         privatestatic int roomId;

         privateint newRoomId=genId();

         privatestatic int genId(){

                   inttmp=roomId;

                   ++roomId;

                   returntmp;

}

 

3rd初始化块(initialization block)(静态初始化块staticinitialization block/对象初始化块objectinitialization block)

只要构造类对象,初始化块就会被执行。

private int id;

{

     id=1;

}

如果静态域赋值的代码比较复杂可以使用静态初始化块

private static int roomId;

static

{

         Randomr=new Random();

         roomId=r.nextInt(100);

}

 

域初始化和初始化块在构造器代码之前。

4th ctor中调用另一个ctor:调用另一个ctor必须放在第一行,this(…)/super(…)

ClassName(){

this(“Alex”);

this.age=10;

}


5th

无参数的ctor 

带参数的ctor的参数名:应当使用this.name=name这种形式,比较直观。


六、包

一个类可以使用其所属包中的所有类,以及其他包中的public类(一个源文件只能有一个public类)

 

访问另一个包中公有类的方法

1在每个类名前添加完整的包名

2导入(类):

import java.util.*;

         只能使用一个*。java.*.*是不可以的

         类命名冲突时必须使用完整包名

         编译器认为嵌套的包之间没有任何关系。java.util包与java.util.jar包相互独立的类集合

 

静态导入静态方法和静态类

import static java.lang.System.*;

import static java.lang.System.out;

 

将类放入包中:源文件第一行应当是package xxx;

若没有在源文件中写package语句,则将类放置在默认包中。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值