好久没来园子了,春节刚过完,现在面对大家最想说的一句话是:你相亲了吗?
都说:孤独的男人玩dota,寂寞的女人穿丝袜。 我想现在这个时代屌丝才会天天上QQ、逛校内、跑猫扑、走天涯,没事发几句牢骚,
没事在微博追追某个名人;至于那些高富帅不是驾着法拉利兜风,就是开着保时捷泡妞,亦或者坐在捷豹上在高速路上狂飙。
记得是去年刚开博的时候,说了些关于Delphi的文字,里面提到了类Pascal语言SCL在工控领域的应用,鉴于目前从事工控的朋友对计算
机感兴趣不多,或者说都认为那些关于计算机的内容太难,同时据我所知国内目前还没有一本关于SCL的教材,于是当时就着手开始编制
一本教程;想着为同行提供一个方便的查阅工具吧,毕竟国内很多的设备都用到了SCL这个PLC的编程工具,当时在园子里面也挂了一些文字,现
在提供一个关于这本教材的试读章节,目前这些文字已经到了第四章了,预计今年7月份能够完成初稿。
【西门子S7 300 400 SCL编程】下载页面:http://www.gongkong365.com/bbs/read.php?tid=34524
下载链接:http://www.gongkong365.com/bbs/job.php?action=download&aid=26976
目前这个文档是DOC格式的,等弄完后,计划编排成PDF格式的,如果可能的话也许会弄成纸质的吧;这里就不多说了。
那么这次我们说点Java的什么内容呢?
【Java中的构造器】
上一次的文字,说了部分关于OOP的内容,同时在文章中我们设计一个Employ类,这个类具有下面的几个域:
private String Name; private boolean Gender; private String PhoneNumber; private double Salary;
这里要说的构造器的作用:构造器的作用就是当系统构造对象的时候,构造器初始化对象。构造器由构造器方法或者构造器函数实现,构造器
方法/函数与类名一致。如下所示:
public employee(String inName,boolean inGender,String inPhoneNumber,double inSalary) { }
这个公有的employee方法就是类employee的构造器(为了方便以后构造器方法和函数均称构造器)。为了实现构造器初始化实例域的目的我们
需要在构造器中添加语句。下面是我们一般的实现:
public employee(String inName,boolean inGender,String inPhoneNumber,double inSalary) { Name=inName; Gender=inGender; PhoneNumber=inPhoneNumber; Salary=inSalary; }
当构造对象的时候,构造器被调用,构造器就将对象的实例域初始化为指定的值。例如当我们用下面的语句构造对象时:
new employee("volcanol",true,“13555555555”,1000.0);
新的对象就具有以下的实例域值:
Name=“volcanol”
Gender=true;
Phonenumber=“13555555555”;
Salary=1000.0;
构造器与其他的方法和函数不同,构造器需要和new操作符一起使用,通过new操作符申请存储空间,而通过构造器对对象进行
初始化。
同时不能对已经存在的对象调用其构造器,这样会导致异常。
构造器要点: 1、 构造器与类同名
2、每个类可以一个以上的构造器
3、构造器可以有0个、1个或者1个以上的参数
4、构造器没有返回值,这个比较重要。
5、构造器总是和new操作符一起使用
6、不要再构造器中定义与类实例域同名的局部变量。
【显示参数和隐式参数】
方法用来操作对象以及存取对象的实例域。例如方法:
public boolean setName(String inName) { if(inName.equals("") || inName==null) { System.out.println("You have input wrong name,Please try again:"); return false; } else { Name=inName; } }
这里这个方法用来对类的实例域name进行设置,同时为了防止输出错误,我们可以用一个循环驱动,直到输入正确为之。
假设我们已经构造了一个对象, employee1,那么就可以调用这个方法了:
employee1.setName("volcanol");
调用方法后就将对象的实例域name设置为volcanol了;实际上setName在调用的过程中有两个参数,一个是显示参数inName
一个是隐式参数,就是方法前的employee1对象,显示参数在参数列表中给出,隐式参数没有出现在参数列表中。
在每一个方法中,用关键字this表示隐式参数,this参数表示对象本身。例如我们可以这样编写方法:
public boolean setName(String inName) { if(inName.equals("") || inName==null) { System.out.println("You have input wrong parment"); return false; } else { this.Name=inName; //显示的调用了隐式参数this } }
这里我们可以看到利用更改器方法,可以对输入参数进行检验,可以减少异常出现的机会,因此这也是一种容错的机制。
【访问器方法和封装】
在我们设计的employee类中,设置了几个访问器方法:
public String getName() { return Name; } public boolean getGender() { return Gender; } public String getPhoneNumber() { return PhoneNumber; } public double getSalary() { return Salary; }
这些方法有一个特点:方法简单的返回实例域的值,那么为什么我们不将实例域设计成public属性,而要设计为private的属性呢?
这里在于通常设置好雇员的某些信息后就不需要再修改,例如名字、生日、住址、身份证号等等信息,为了防止这些新被意外的修改,我们
就是用这种机制来避免非法的修改。
我们将所有的实例域都设计为private的后,而有些内容还需要进行修改,那么我们就可以根据实际的应用,为类的实例域设计:
1、获取实例域访问器方法
2、修改实例域的更改器方法
这样做是为了提高封装性,封装后代码会变复杂,当然这也是有优势的:
1、当方法的接口不变的时候,可以对类的实现进行任意的修改,而不会影响对象的使用者。
2、可以对数据进行容错检测,例如可以检查输入的inName参数是否为空。
【关于private和final】
接触过C++的童鞋,应该知道在C++的访问控制策略上面有几个:public、private、protected等访问控制策略,
在Java中也有几种访问控制策略:
1、public: 公有访问策略,就是域可以被类的对象自己访问,也可以被其他类的对象访问
2、private: 定义为private的域可以被类的对象自己访问,但是不能被其他类的对象访问
同时定义为private的方法可以任意修改对象的接口,设置将方法删除,而不会影响对象使用者造成影响,当然这样做的时候,
需要类的设计者重新构建类。
因此如果一个类的某个域不想被其他类的对象引用,那么最合适的方法就是将其设计为private的访问控制策略。
前面说过这个关键字:final。 这个关键字声明或者定义的对象和C++语言中的const 变量有点类似,但是又不完全一样,需要注意
分辨。
在Java中定义为final的对象或者变量,一旦初始化后就不再能改变。这就是说如果一个类中设计了final的实例域,那么必须在类的构造
器中对其进行初始化;同时还需要在以后的引用过程中不对这样的实例域进行改写,即不能用更改器方法访问final属性实例域。
例如:
private final String Name;
就是说一个雇员的姓名注册到公司的信息系统后除非雇员对象被删除/注销,否则雇员的Name域就不能改变。
这里有一点需要说明的:
1、final修饰符一般应用于基本数据类型的域,或者不可变类的数据域。
2、final修饰符修饰可变对象的时候,并不是指对象不可变,这里容易造成混淆。(是否指的是其引用指向不能改变??这个问题需要继续研究)。
例如我们设计这样一个域:
private final Date Birthday;
当用构造器构造对象后,其他对象可以调用Birthday的方法来改变对象的。
【静态域和静态方法】
1、静态域
通过关键字static来定义类的静态域,类中定义静态域后,类的所有实例共享同一块内存代表的静态域。
例如:
class employee
{
private int id;
private static int nextId=1;
}
如果用这个类定义实例化对象,则所有的对象共享一个nextId静态域空间,一个对象改变这个静态域则其他对象关于这个
静态域的引用都将改变。
如果一个类中定义了静态域,即使不实例化对象,静态域nextId静态域也存在,静态域属于类,而不属于任何独立的对象。
这里还有一个需要注意的地方:
类的非静态域需要通过类的对象引用,而静态域可以通过类来引用,即我们可以如下引用静态域:
employee.nextId=xx;
2、静态常量
在类中可以定义静态常量,例如在类Math中定义了一个静态常量:
public class Math
{
........
public static final double PI=3.14159265358979323846;
..........
}
这样在程序中不需要实例化对象就可以引用这个静态域常量。例如:
s=r*r*Math.PI; //面积=PI*r^2
而如果将关键字省略,则PI变成Math类的一个实例域,那时就需要通过Math类的对象访问PI,并且每一个Math对象
都将有一个PI的副本。
3、静态方法
静态方法不能向对象实施操作。我们知道在Math类中有一个pow方法,这个方法就是一个静态方法,
通过下面的方式来调用pow方法:
Math.pow(x,a) //计算机x^a 的结果,在运算时不使用任何Math对象,即没有隐式参数this。
静态方法不能操作对象,所以不能在静态方法中访问非静态实例域; 在静态方法中可以访问自身类中的静态域。
例如:
public static int getNextId()
{
return nextId ; // static nextId
}
则可以通过类名调用这个方法:
int n=employee.getNextId();
当然此时我们也可以通过对象调用这个方法: int n1= employee1.getNextId();
通常在下面情况下使用静态方法:
1、一个方法不需要访问对象的状态,其所需的参数通过显示提供。
2、一个类的方法只需要访问类的静态域。
4、main方法
每个类都可以有一个main方法,但是在应用程序中每个类的main方法不一定都被执行。
这里需要注意,main方法必须定义为static的,同时我们可以单独对某个类进行测试。
例如定义了一个应用程序application。
public class application
{
statement....
employee employee1=new employee();
}
public class employee
{
public static main(String[] args[])
{
statement......
}
}
我们可以单独编译employee类: java employee; 这时仅对employee类进行测试,不会应用程序中的其他类,除非在employee中
引用了其他类。
也可以编译整个应用程序: java application; 这时employee类中的main方法将不能被执行,也就是说应用程序的可以有多个类拥有
main方法,但是应用程序只有一个入口。
今天就说到这,接下来就是类方法参数的内容了。
这里还有一个问题不太明白,这里不知哪位大神解释一下就是上面的文字中关于:final关键字。(是否指的是其引用指向不能改变??这个问题需要继续研究)。