-----------android培训、java培训、java学习型技术博客、期待与您交流! ------------
一、构造函数
1、构造函数的特点:
2、构造函数的作用:
3、构造函数细节:
(2)如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。
这个时候,你可以不使用无参构造方法。
如果你想使用,那么,就必须手动给出无参构造方法。
建议:一般情况下,我们的自定义类都要手动给出无参构造方法。
4、构造方法和成员方法的区别
(1)格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值。
普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
(2)作用区别
构造方法用于创建对象,并进行初始化。
普通成员方法是用于完成特定功能的。
(3)调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
5、构造函数的调用限制
(2)一般函数不能调用构造函数,因为this语句只能用在构造函数中,不能用在一般语句中。
二、构造代码块:
1、作用:
给对象进行初始化,对象一建立就执行,而且优先于构造函数执行。
2、构造代码块和构造函数的区别:
(1)构造代码块是给所有不同对象的共性进行统一初始化;
(2)构造函数是给对应的对象进行初始化 。
构造代码快中定义的是不同对象共性的初始化内容。
//下面就是构造代码块
{
System.out.println("person code run");
cry();
}
三、this关键字:
1、定义:
当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。
2、引入this的原因:
希望在方法的内部获得对当前对象的引用。
3、this的特性:
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
this的用法和其他对象引用并无不同。
this只能在类中的非静态方法中使用;静态方法和静态的代码块中绝对不能出现this。
this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。
4、this的应用:
(1)用于区分同名成员变量和局部变量(表象);
函数参数或者函数中的局部变量和成员变量同名的情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。当然,在没有同名的情况下,可以直接用成员变量的名字,而不用this,用了也不为错.
(2)在定义类中的函数时,该函数内部要引用调用该函数的对象时,因为此时对象还没建立,故this代表此对象(本质原因)
例子:比较两个人的年龄
(3)构造函数间调用,只能用this语句
注意,如果我们想在一个构造函数中对另一个构造函数进行调用的时候,不能在其构造函数中直接类名(参数)这样调用,而是通过this调用另一个构造方法,用法是this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。这叫this语句。
使用规则:这个时候,this(参数)必须作为第一条语句存在(因为初始化要先执行)。
使用场合:构造函数有多个,但是只对外提供一个,内部却有多种初始化方式,可以将其私有起来,进行内部初始化动作
其实这些用法总结都是从对“this是指向对象本身的一个指针”这句话的更深入的理解而来的,死记不然容易忘记而且容易搞错,要理解!
//比较两个人的年龄是否相同 class Demo { public static void main(String[] args) { Person p1= new Person(20); Person p2= new Person(25); boolean b = p1.compare(p2);//比较年龄大小 System.out.println(b); } } class Person { private int age; Person(int age)//构造函数 { this.age=age; } public boolean compare(Person p) { return this.age==p.age;//this代表的是P1,因为是P1调用了该方法。然后和P2进行比较大小 } }
/* this语句 :用于构造函数之间进行互相调用。 this语句只能定义在构造函数的第一行。因为初始化要先执行。 */ class Demo { public static void main(String[] args) { //创建对象就用调用Person初始化构造函数 Person p1= new Person("lisi",20); Person p2= new Person("wangwu",25); } } class Person { private int age; private String name; Person() { System.out.println("你好"); } Person(int age) { this(); this.age=age; } Person(String name,int age) { this(age);//通过this调用 this.name=name; } }
四、static 关键字:
1、用法:
是一个修饰符,用于修饰成员(成员变量,成员函数)。
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。即:类名.静态成员。
2、被静态修饰后的成员具备以下的特点:
3、静态变量(类变量)和成员变量(实例变量)的区别:
(1)存储位置
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
成员变量随着对象的创建而存在,随着对象的消失而消失。
(3)所属不同(与对象的相关性):
静态变量也称之为类变量,所属于整个类,被该类的所有对象共享。
实例变量是每个对象的特有数据,所属于特定对象。
(4)调用方式:
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。这个变量属于类。
成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
4、静态使用注意事项:
(1)静态方法只能访问静态成员;非静态方法既可以访问静态也可以访问非静态。
原因:原因:因为静态的内容是随着类的加载而加载,它是先进内存的。
(2)静态方法中不能使用this,super关键字。
原因:原因:因为静态优先于对象存在,所以静态方法中不可以出现this。
(3)主方法是静态的。
publicstatic void main(String[] args)
5、静态的优点和弊端:
6、什么时候使用静态呢?
五、主函数
1、定义:
是一个特殊的函数。作为程序的入口,可以被jvm调用。
publicstatic void main(String[] args)
2、修饰符含义:
public:公共的意思,是最大权限修饰符。
static:由于jvm调用main方法的时候,没有创建对象,只能通过类名调用。所以,main必须用static修饰。代表主函数随着类的加载就已经存在了。
void:由于main方法是被jvm调用,不需要返回值。必须用void修饰。
main:main是主要的意思,所以jvm采用了这个名字。是程序的入口。
String[]:函数的参数,参数类型是一个数组,该数组中的元素是字符串。即:字符串类型的数组。Jvm只认这个。
args:数组名。这是主函数中唯一能改动的地方。
3、补充:
主函数是固定格式的 ,被jvm识别
默认情况下,jvm在调用主函数时,传入的是new String[0],该数组长度为0。
在运行的时候,可以通过java命令给args数组赋值。
格式:java MainTest hello world itcast
六、静态的应用:工具类
/*
静态的应用。
每一个应用程序中都有共性的功能,
可以将这些功能进行抽取,独立封装。
以便复用。
虽然可以通过建立ArrayTool的对象使用这些工具方法,对数组进行操作。
发现了问题:
1,对象是用于封装数据的,可是ArrayTool对象并未封装特有数据。
2,操作数组的每一个方法都没有用到ArrayTool对象中的特有数据。
这时就考虑,让程序更严谨,是不需要对象的。
可以将ArrayTool中的方法都定义成static的。直接通过类名调用即可。
将方法都静态后,可以方便于使用,但是该类还是可以被其他程序建立对象的。
为了更为严谨,强制让该类不能建立对象。
可以通过将构造函数私有化完成。
接下来,将ArrayTool.class文件发送给其他人,其他人只要将该文件设置到classpath路径下,就可以使用该工具类。
但是,很遗憾,该类中到底定义了多少个方法,对方去不清楚。因为该类并没有使用说明书。
开始制作程序的说明书。java的说明书通过文档注释来完成。
*/
/**
这是一个可以对数组进行操作的工具类,该类中提供了,获取最值,排序等功能。
@author 张三
@version V1.1
*/
//javadoc -d myhelp -author -version ArrayTool.java
public class ArrayTool
{
/**
空参数构造函数。
*/
private ArrayTool(){}
/**
获取一个整形数组中的最大值。
@param arr 接收一个int类型的数组。
@return 会返回一个该数组中最大值。
*/
public static int getMax(int[] arr)
{
int max = 0;
for(int x=1; x<arr.length; x++)
{
if(arr[x]>arr[max])
max = x;
}
return arr[max];
}
/**
获取一个整形数组中的最小值。
@param arr 接收一个int类型的数组。
@return 会返回一个该数组中最小值。
*/
public static int getMin(int[] arr)
{
int min = 0;
for(int x=1; x<arr.length; x++)
{
if(arr[x]<arr[min])
min = x;
}
return arr[min];
}
/**
给int数组进行选择排序。
@param arr 接收一个int类型的数组。
*/
public static void selectSort(int[] arr)
{
for (int x=0; x<arr.length-1 ; x++ )
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
swap(arr,x,y);
}
}
}
}
/**
给int数组进行冒泡排序。
@param arr 接收一个int类型的数组。
*/
public static void bubbleSort(int[] arr)
{
for (int x=0; x<arr.length-1 ; x++ )
{
for(int y=0; y<arr.length-x-1; y++)
{
if(arr[y]>arr[y+1])
{
swap(arr,y,y+1);
}
}
}
}
/**
给数组中元素进行位置的置换。
@param arr 接收一个int类型的数组。
@param a 要置换的位置
@param b 要置换的位置
*/
private static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
/**
用于打印数组中的元素。打印形式是:[elemet1, element2, ...]
*/
public static void printArray(int[] arr)
{
System.out.print("[");
for(int x=0; x<arr.length; x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+", ");
else
System.out.println(arr[x]+"]");
}
}
}
/*
一个类中默认会有一个空参数的构造函数,
这个默认的构造函数的权限和所属类一致。
如果类被public修饰,那么默认的构造函数也带public修饰符。
如果类没有被public修饰,那么默认的构造函数,也没有public修饰。
默认构造构造函数的权限是随着的类的变化而变化的。
*/
七、静态代码块:
格式: static { 静态代码块中的执行语句。 } 特点:随着类的加载而执行,只执行一次,并优先于主函数。 作用:用于给类进行初始化的。
class StaticCode//代码演示:
{
int num = 9;
StaticCode()
{
System.out.println("b");
}
{
System.out.println("c"+this.num);//构造代码块,没创建一个对象都调用。调用在静态代码块之后
}
static
{
System.out.println("a");
}
StaticCode(int x)
{
System.out.println("d");
}
}
class Demo
{
static
{
System.out.println("b");//静态代码块只调用一次
}
public static void main(String[] args)
{
new StaticCode(4);
new StaticCode(4);
}
static
{
System.out.println("c");
}
}
/*打印结果是
b
c
a
c9
d
c9
d*/
八、代码块集锦
1、局部代码块,构造代码块,静态代码块
(1)局部代码块:
(2)构造代码块:
(3)静态代码块:
2、静态代码块和构造代码块:
九、(重点)Person p = new Person();
(2)该类中如果有静态代码块,就执行,给Person类进行初始化。
(3)如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。
(4)在堆内存给对象分配空间。
(5)在堆内存中建立对象的特有属性,并对属性进行默认初始化。
(6)对对象的属性进行 显式初始化( 由编写的人员通过代码语句进行初始化 ) 。
(7)调用构造代码块对对象进行初始化。(如果没有就不执行)
(8)调用构造方法对对象进行初始化。对象初始化完毕。
(9)将对象的内存地址赋值给p变量,让p变量指向该对象。
class Person
{
private Person(){}
private String name = "hah";
private int age;
private static String country = "cn";
Person(String name,int age)
{
this.name = name;
this.age = age;
}
{
System.out.println(name+".."+age);
}
public void setName(String name)
{
this.name = name;
}
public void speak()
{
System.out.println(this.name+"..."+this.age);
}
public static void showCountry()
{
System.out.println("country="+Person.country);
Person.method();
}
public static void method()
{
System.out.println("method run");
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person("zhangsan",20);
p.setName("lisi");
new Person();
}
}
class Soap {
private String s;
Soap() {
print("Soap()");
s = "Constructed";
}
public String toString() {
return s;
}
}
public class Bath {
private String // Initializing at point of definition:定义初始化
s1 = "Happy",
s2 = "Happy", s3, s4;
private Soap castille;
private int i;
private float toy;
public Bath() {//构造器初始化
print("Inside Bath()");
s3 = "Joy";
toy = 3.14f;
castille = new Soap();
}
// Instance initialization:构造代码块,优先于构造器执行
{
i = 47;
}
public String toString() {
if (s4 == null) // Delayed initialization:当toString()被调用时,惰性初始化
s4 = "Joy";
return
"s1 = " + s1 + "\n" +
"s2 = " + s2 + "\n" +
"s3 = " + s3 + "\n" +
"s4 = " + s4 + "\n" +
"i = " + i + "\n" +
"toy = " + toy + "\n" +
"castille = " + castille;
}
public static void main(String[] args) {
Bath b = new Bath();
System.out.println(b);
}
}
/*
* Output:
Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed
*/// :~