类的成员之三:构造器(或构造方法、constructor)的使用
一、构造器的特征
它具有与类相同的名称
它不声明返回值类型。(与声明为void不同)
不能被static、final、synchronized、abstract、native修饰,不能有 return语句返回值
语法格式: 修饰符 类名 (参数列表) { 初始化语句; }
//构造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
二、构造器的作用:创建对象;给对象进行初始化
如:Order o = new Order(); Person p = new Person(“Peter”,15);
如同我们规定每个“人”一出生就必须先洗澡,我们就可以在“人”的 构造器中加入完成“洗澡”的程序代码,于是每个“人”一出生就会自 动完成“洗澡”,程序就不必再在每个人刚出生时一个一个地告诉他们 要“洗澡”了。
三、说明:
1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器。默认构造器的修饰符与所属类的修饰符一致 。
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载。构造器重载,参数列表必须不同。
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器。
5.一个类中,至少会有一个构造器。父类的构造器不可被子类继承。
四、构造器使用示例
public class PersonTest {
public static void main(String[] args) {
//创建类的对象:new + 构造器
Person p = new Person();
p.eat();
Person p1 = new Person("Tom");//Tom赋值给构造器中的形参
System.out.println(p1.name);//Tom
}
}
class Person{
//属性
String name;
int age;
//构造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
//
public Person(String n,int a){
name = n;
age = a;
}
//方法
public void eat(){
System.out.println("人吃饭");
}
public void study(){
System.out.println("人可以学习");
}
}
五、总结:赋值属性的过程
1.赋值的位置:
① 默认初始化
② 显式初始化
③ 构造器中初始化
④ 通过“对象.属性“或“对象.方法”的方式赋值
⑤在代码块中赋值
2.赋值的先后顺序: ① - ② / ⑤ - ③ - ④
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age); //1
User u1 = new User(2);
System.out.println(u1.age); //2
u1.setAge(3);
u1.setAge(5);
System.out.println(u1.age); //5
}
}
class User{
String name;
int age = 1;
public User(){
}
public User(int a){
age = a;
}
public void setAge(int a){
age = a;
}
}
六、JavaBean
JavaBean是一种Java语言写成的可重用组件。
所谓javaBean,是指符合如下标准的Java类:(1)类是公共的 ( 2)有一个无参的公共的构造器 (3)有属性,且有对应的get、set方法
用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以 用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP 页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用 户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关 心任何改变。
public class Customer {
private int id;//属性一般定义为private
private String name;
public Customer(){
}
public void setId(int i){
id = i;
}
public int getId(){
return id;
}
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
}
七、UML类图
类的成员之四:代码块(或初始化块)
一、代码块(或初始化块)的作用:
对Java类或对象进行初始化
二、代码块(或初始化块)的分类:
一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块 。
没有使用static修饰的,为非静态代码块。
静态代码块:用static 修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5. 静态代码块的执行要先于非静态代码块。
6. 静态代码块随着类的加载而执行,且只执行一次。
非静态代码块:没有static修饰的代码块
1. 可以有输出语句。
2. 可以在创建对象时,对对象的属性进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
public class BlockTest {
public static void main(String[] args) {
String desc = Person.desc;
System.out.println(desc);
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.age);
Person.info();
}
}
class Person{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//非static的代码块
{
System.out.println("hello, block - 2");
}
{
System.out.println("hello, block - 1");
//调用非静态结构
age = 1;
eat();
//调用静态结构
desc = "我是一个爱学习的人1";
info();
}
//static的代码块
static{
System.out.println("hello,static block-2");
}
static{
System.out.println("hello,static block-1");
//调用静态结构
desc = "我是一个爱学习的人";
info();
//不可以调用非静态结构
// eat();
// name = "Tom";
}
//方法
public void eat(){
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void info(){
System.out.println("我是一个快乐的人!");
}
}
类的成员之五:内部类(Inner clas)
Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类。
内部类的分类:
成员内部类(静态、非静态)
局部内部类(方法内、代码块内、构造器内)
如何使用局部内部类
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方 都不能使用该类 。
但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类 的父类或父接口类型。
在局部内部类的方法中如果调用局部内部类所声明的方法中的局部变量的话,要求此局部变量声明为final的。
public class InnerClassTest1 {
//开发中很少见
public void method(){
//局部内部类
class AA{
}
}
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:创建了一个实现Comparable接口的匿名实现类的匿名对象
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
成员内部类作为类的成员的角色:
和外部类不同,Inner class还可以声明为private或protected。
可以调用外部类的结构。
Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员 变量。
成员内部类作为类的角色:
可以在内部定义属性、方法、构造器等结构。
可以声明为abstract类 ,表示此类不能实例化。
可以声明为final的,表示此类不能被继承。言外之意,不使用final,就可以被继承。
编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)。
【注意】
非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员 内部类中才可声明static成员。
外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式。
成员内部类可以直接使用外部类的所有成员,包括私有的数据。
当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的。
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println("卡拉是条狗");
// eat();
}
}
//非静态成员内部类
class Bird{
String name = "杜鹃";
public Bird(){
}
public void sing(){
System.out.println("我是一只小小鸟");
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}