在日常的Java项目开发中,entity(实体类)是必不可少的,它们一般都有很多的属性,并有相应的setter和getter方法。entity(实体类)的作用一般是和数据表做映射。所以快速写出规范的entity(实体类)是java开发中一项必不可少的技能。
大概的说,实体类就是:属性+get/set方法。
在项目中写实体类一般遵循下面的规范:
1、实体类的名字尽量和数据库的表的名字对应相同。
2、根据你的设计,定义一组你需要的私有属性。(如:private int age;)
3、根据这些属性,创建它们的setter和getter方法。(AndroidStudio 等集成开发软件可以自动生成。具体怎么生成请自行百度。)
4、提供有参数的构造器(所有的参数)和无参数的构造器。(如果你不手动写上构造方法。会默认帮你加上一个无参构造方法[不会显示出来])
关于构造器可以看看这几篇文章(在下面我也会大概说下):构造器的作用是什么? , Java构造器和方法的区别 ,
5、重写父类中的eauals()方法和hashcode()方法。(如果需要涉及到两个对象之间的比较,这两个功能很重要。)
关于重写这两个方法的原因可以看看这几篇文章: 重写equals和 hashCode方法 ,为什么重写equals的同时必须重写 hashcode,为什么要重写equals
如何重写hashCode()和equals()方法1 , 如何重写equals和 hashCode方法2
6、实体类应该实现Serializable接口(序列化)。(如:public class BaseEntity implements Serializable { } )
实体类为什么要序列化请参考这篇文章和这个贴: java实体类实现序列化的意义 (详细的解析) 和 Java序列化的意义(通俗易懂)
关于serialVersionUID作用介绍请看两篇文章: serialVersionUID作用 和 AndroidStudio自动生成SerialVersionUID方法
下面是我写的一个实体类(entity)例子:具体的细节都用注释标注了。
/**一个学生的Java实体类*/
class Student implements Serializable{
/**
* 序列化版本号(自动生成,方法请看上面)
*/
private static final long serialVersionUID = 88722423642445L;
//定义的私有属性
private int id;
private String name;
private int age;
private double score;
//无参数的构造器(如果不写系统会自动生成无参数的构造器,但不会显示出来)
public Student(){
}
//有参数的构造器
public Student(int id,String name,int age, double score){
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
//创建的setter和getter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
//由于id对于学生这个类是唯一可以标识的,所以重写了父类中的id的hashCode()和equals()方法。
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (id != other.id)
return false;
return true;
}
}
public class Animal {
private int legs;
//无参构造器
public Animal() {
legs = 4;
}
//有参构造器
public Animal(int legs) {
this.legs = legs;
}
public void setLegs(int i) { legs = i; }
public int getLegs(){return legs;}
}
创建Animal类的实例:Animal a=new Animal(); //调用无参构造器,将legs初始化为4;(即 a.legs=4)
/**
* 声明抽象类;
*
* (父类)
**/
abstract class Animal{
private String name;
public Animal(String name){
this.name = name;
}
public abstract void enjoy(); //声明抽象方法
}
/**
* 继承抽象类;
*
**/
class Dog extends Animal{
private String forlorColor;
public Dog(String name,String forlorColor){
super(name);
this.forlorColor = forlorColor;
}
// 实现抽象类里面的抽象方法 (即加些功能)
protected void enjoy(){
System.out.println("dog叫声~~~");
}
}
/**
* 继承activity的抽象类
*/
public abstract class BaseActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//子类继承该抽象类BaseActivity后就会按着这些抽象方法一步一步执行
findViews(); //先 绑定控件
init(); //然后 初始化视图
setListeners(); //最后 设置监听器
}
//声明抽象方法
protected abstract void findViews();
protected abstract void init();
protected abstract void setListeners();
}
/**
* 继承抽象类,实现里面的抽象方法
*/
public class MainActivity extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// 实现下面 抽象类里面的抽象方法 (即加些功能等)
@Override
protected void findViews() {
// TODO Auto-generated method stub
//先在这里绑定控件
}
@Override
protected void init() {
// TODO Auto-generated method stub
//然后初始化视图
}
@Override
protected void setListeners() {
// TODO Auto-generated method stub
//最后 设置监听器
}
}
网上有很多介绍BaseActivity的博文,多数是从应用的角度去描述的。
这里,我所介绍的BaseActivity不同,主要从框架搭建的角度去介绍BaseActivity的使用。
先看代码:
/**
* 应用程序Activity的基类
*/
public abstract class BaseActivity extends Activity implements
OnClickListener {
private static final int ACTIVITY_RESUME = 0;
private static final int ACTIVITY_STOP = 1;
private static final int ACTIVITY_PAUSE = 2;
private static final int ACTIVITY_DESTROY = 3;
public int activityState;
// 是否允许全屏
private boolean mAllowFullScreen = true;
//声明抽象方法
public abstract void initWidget();
public abstract void widgetClick(View v);
public void setAllowFullScreen(boolean allowFullScreen) {
this.mAllowFullScreen = allowFullScreen;
}
@Override
public void onClick(View v) {
widgetClick(v);
}
/***************************************************************************
*
* 打印Activity生命周期
*
***************************************************************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppLog.debug(this.getClass() + "---------onCreat ");
// 竖屏锁定
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if (mAllowFullScreen) {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 取消标题
}
AppManager.getAppManager().addActivity(this);
initWidget();
}
@Override
protected void onStart() {
super.onStart();
AppLog.state(this.getClass(), "---------onStart ");
}
@Override
protected void onResume() {
super.onResume();
activityState = ACTIVITY_RESUME;
AppLog.state(this.getClass(), "---------onResume ");
}
@Override
protected void onStop() {
super.onResume();
activityState = ACTIVITY_STOP;
AppLog.state(this.getClass(), "---------onStop ");
}
@Override
protected void onPause() {
super.onPause();
activityState = ACTIVITY_PAUSE;
AppLog.state(this.getClass(), "---------onPause ");
}
@Override
protected void onRestart() {
super.onRestart();
AppLog.state(this.getClass(), "---------onRestart ");
}
@Override
protected void onDestroy() {
super.onDestroy();
activityState = ACTIVITY_DESTROY;
AppLog.state(this.getClass(), "---------onDestroy ");
AppManager.getAppManager().finishActivity(this);
}
}
定义一个初始化Activity控件的抽象方法initWidget();
像findviewbyid()这类代码就可以写在这里,不会影响代码结构了。这里需要提一点的是:setContent()方法一定要写在initWidget()里,而不能再写到oncreate里面了,看代码可以知道,initwidget方法是存在于super()中的,而如果再写到oncreate里,就相当于先调用了findview再去调用setcontent,这样肯定会报空指针异常。
关于竖屏锁定,这个可以按需要添加,没什么说的。
还有一个要说的就是requestWindowFeature(Window.FEATURE_NO_TITLE); // 取消标题
对于这段代码,如果你要使用系统的ActionBar的时候,一点要记得调用setAllowFullScreen,设置为false,否则BaseActivity自动取消了ActionBar你又去使用,肯定也会出异常。
还有一点:Baseactivity已经实现了OnClickListener,所以子类无需再次实现,控件可以直接在initWidget里面setonclicklistener(this);然后在widgetClick(View v)中设置监听事件即可。
有关AppManager的内容我将放到下一篇《Android应用框架搭建》去讲解,这里大家可以先忽略。
有关生命周期的打印,我认为在调试阶段还是有必要的,毕竟看着每一个Activity的生命周期,如果出了问题马上就可以清楚的知道是哪里出了问题