实例化一个类的对象后,如果要为这个对象中的属性赋值,则必须要通过直接访问对象的属性或调用setXxx()方法的方式才可以实现。如果需要在实例化对象的同时就为这个对象的属性赋值,可以通过构造方法来实现。
构造方法是类的一个特殊的成员,它会在类实例化对象时被自动调用。
作用就是在创建对象的时候,给对象的成员变量赋初始值。
写法:
- 函数名:必须和类名一致(包括大小写)。
- 返回值类型:没有返回值类型,void都不能写。
- return:构造函数可以有return,但是不能有返回值,一般不书写return。
示例:
class Student {// 创建一个类
private String name;// 私有化属性
private String sex;
private int age;
// 无参的构造方法,即使不书写,默认也是这个
// 当有参构造方法存在时,无参的构造方法最好也书写上,不然无法通过 new 类名()的方式实例对象
public Student() {
}
// 有参构造方法,实例对象的同时给属性赋值
public Student(String n, String s, int a) {
name = n;
sex = s;
age = a;
}
}
构造函数和一般函数的区别:
1、从书写格式上看:
a) 构造函数:没有返回值类型;函数名必须和类名一致。
b) 一般函数:必须有返回值类型;函数名可以自定义;一般不要和类名一样;如果函数的名字和类名一样,判断是不是构造函数,就通过有没有返回值类型来确定。
2、从调用方式上看:
a) 构造函数: 在创建对象时,由JVM自动调用。
b) 一般函数: 创建对象后,由对象名来调用。
3、从作用上看:
a) 构造函数:在创建对象时,就给成员变量赋值。
b) 一般函数:实现各种功能,描述事物的行为信息。
4、从一个对象可以调用次数上看:
a) 构造函数:只在创建对象时被调用一次。
b) 一般函数:可以使用对象名调用无数次。
Static和This:
class Student {// 创建一个类
private String name;// 私有化属性
private String sex;
private int age;
static String classes;// 创建一个静态变量,这个变量所有的实例都会使用同一个
// 无参的构造方法,即使不书写,默认也是这个
// 当有参构造方法存在时,无参的构造方法最好也书写上,不然无法通过 new 类名()的方式实例对象
public Student() {
}
// 有参构造方法,实例对象的同时给属性赋值
public Student(String n, String sex) {
name = n;
// 局部变量测名和成员变量名一样,可以用this关键字来区分
// this表示当前的,在类里面一般表示当前类
this.sex = sex;
}
// 有参构造方法,实例对象的同时给属性赋值
public Student(String n, String s, int a) {
// this() 可以调用自身已经存在的构造函数,
// this()必须放在第一行
this(n, s);
age = a;
}
public void speak() {
// 非静态的方法只能通过实例对象来调用
System.out.println("大家好,我是" + name + ",今年" + age + ",我是" + sex + "的" + ",我在" + classes + "班");
}
public static void staticVoid() {
System.out.println("这是一个静态方法,允许通过(实例对象.方法名) 或 (类名.方法名)调用");
}
private void privateVoid() {
// (实例对象.方法名) 或 (类名.方法名)都不能调用这个函数
System.out.println("这是一个私有方法,只有在当前类中才可以被调用");
}
}
public class ClassTest {
public static void main(String[] args) {
Student student = new Student();// 创建一个对象
System.out.println(student);// 直接打印创建的类对象观察结果
System.out.println(student.toString());// 对比前一条输出结果
Student s2 = new Student("小白", "女", 18);
s2.speak();
// Student.classes = "Java班";//静态变量和静态方法可以(实例对象.方法名) 或 (类名.方法名)调用
s2.classes = "Java班";// 执行效果和前一句一样
s2.speak();
Student s3 = new Student("小华", "男");
s3.speak();// 小华未设置班级,观察输出
Student.classes = "Java";
s2.speak();
Student.staticVoid();// 调用Student的静态方法
s2.staticVoid();// 调用Student的静态方法
// Student.speak();// 非静态的方法无法通过(类名.方法名)来调用
System.out.println("======================");
System.out.println(s2);// 观察s2和s3,思考以下输出结果的原因
System.out.println(s3);
s3 = s2;//
s2.speak();
s3.speak();
System.out.println(s2);
System.out.println(s3);
s2 = null;
System.out.println(s2);
System.out.println(s3);
}
}
运行结果:
单例模式:
单例模式是指一个类不管被new多少次,只存在一个对象。就像我们生存的世界只有一个太阳,假设现在要设计一个类来表示月亮,该类只能有一个实例对象,否则就违背了事实。
单例模式具备以下特点:
- 类的构造方法私有,即用private修饰,这样在类的外面就没法随便new对象了。
- 类的内部声明一个私有(private)静态(static)的该类的对象作为变量。类的外面不能随意访问这个成员变量。
- 为了让外部能够获得类的实例对象,需要定义一个(static)方法,一般采用getInstance(),用于返回该类的实例。采用(static)修饰,外界可以通过"类名.方法名()"的方式访问。
下面给出单例模式设计的常用两种模式:
//饥汉模式
class SingleTest1 {
int num;
private static SingleTest1 instance = new SingleTest1();
private SingleTest1() {
}
public static SingleTest1 getInstance() {
return instance;
}
}
// 懒汉模式
class SingleTest2 {
int num;
private static SingleTest2 instance;
private SingleTest2() {
}
public static SingleTest2 getInstance() {
// 线程非安全
if (instance == null) {
instance = new SingleTest2();
}
return instance;
}
// public static synchronized SingleTest2 getInstanceL() {
// // 线程安全
// if (instance == null) {
// instance = new SingleTest2();
// }
// return instance;
// }
}
public class Single1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingleTest1 test1 = SingleTest1.getInstance();
test1.num = 100;
SingleTest1 test2 = SingleTest1.getInstance();
System.out.println("test1.num==" + test1.num);
System.out.println("test2.num==" + test2.num);
// SingleTest2 test = new SingleTest2();
SingleTest2 test3 = SingleTest2.getInstance();
test3.num = 90;
SingleTest2 test4 = SingleTest2.getInstance();
test4.num = 9;
System.out.println("test3.num==" + test3.num);
System.out.println("test4.num==" + test4.num);
}
}