构造函数:在创建对象的同时,给对象的赋初值。
构造函数的函数名必须与类名同名.
如:
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c=new CCircle(); //创建一个属于CCircle类的一个对象
//c.color="yellow"; 错误,由于color为私有类型,不能在类外赋值
c.show();
}
}
对象的创建: 类名 对象名 = new 类名();
如果不定义构造函数,那么java会自动调用默认构造函数,如上题:
public CCircle()
{
}
没有任何参数,所以上面的代码输出为:该圆的颜色: null,半径为: 0,面积为: 0.0
但是如果你提供了构造函数(无论是否构造函数中含有参数),那么就不会提供默认的构造函数.
如在类外定义一个构造函数:CCircle(String Color,int Radius)
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
public CCircle(String Color,int Radius)
{
color=Color;
radius=Radius;
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c=new CCircle();
//c.color="yellow"; 错误,由于color为私有类型,不能在类外赋值
c.show();
}
}
这个时候就会出现以下的编译错误:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor CCircle() is undefined. //找不到"没有参数的构造函数"
构造函数调用类中的另外一个构造函数,必须调用this,而不能以构造函数直接调用,否则会出现编译错误。
如:
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
public CCircle()
{
this("red",1); //调用下面的构造函数
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
public CCircle(String Color,int Radius)
{
color=Color;
radius=Radius;
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c=new CCircle();
//c.color="yellow"; 错误,由于color为私有类型,不能在类外赋值
c.show();
}
}
编译结果为:
该圆的颜色: red,半径为: 1,面积为: 3.1415
该圆的颜色: red,半径为: 1,面积为: 3.1415
第一行是调用构造函数输出的结果。
this的用法:
1、this([参数]);且只能放在构造函数的函数体的第一行,否则会出现编译错误。
2、this.成员变量; 表示对当前对象的引用.
如构造函数中变量名可以与成员变量同名,这个时候就要用this表示对当前对象的引用
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
public CCircle()
{
this("red",1); //调用下面的构造函数
System.out.println("this: "+this);
}
public CCircle(String color,int radius)
{
color=color;
radius=radius;
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c=new CCircle();
//c.color="yellow"; 错误,由于color为私有类型,不能在类外赋值
c.show();
}
}
不用this,出现的结果为:
this: CCircle@ecb281 //返回为对象分配的内存,用16进制表示
该圆的颜色: null,半径为: 0,面积为: 0.0
由于没有用this表示对当前对象的引用,调用构造函数Color(String color,int radius)时
color=color,就不知道哪个color赋给哪个color,所以系统就直接赋值为空。
但是用this表示对当前对象的引用后,如:
public Color(String color,int radius)
{
this.color=color;
this.radius=radius;
}
就表示将color赋值给当前对象的this.color。
编译后的结果可想而知为:
this: CCircle@ecb281
该圆的颜色: red,半径为: 1,面积为: 3.1415
前面的第一个代码实际上是省略了this来表示对当前对象的引用,因为并没有出现异常的赋值状况,所以说
在每一个成员变量的调用前加上this关键字后结果依然不变。
如:
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
public double area()
{
return (this.pi)*(this.radius)*(this.radius);
}
public void show()
{
System.out.println("该圆的颜色: "+this.color+",半径为: "+this.radius+",面积为: "+this.area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c=new CCircle();
c.show();
}
}
3、this.成员方法,如上面的代码中this.area().
注意:this只能在当前类里面使用,不能在类外使用,且在static方法中不能使用。
当然构造函数也有公有和私有构造函数,含义和成员变量一样,私有构造函数只能在类里面进行调用,类外部不能被调用。
静态变量:被所有对象共享,只需在变量前加上static修饰符。
被static修饰的变量可以使得该类产生的对象共享同一个static变量。
被修饰的变量放在静态内存,且静态区内存里的数据可以共享。
如上面的代码中我想知道创建了多少个CCircle类的对象,就可以定义一个static的count变量,生成一个对象count+1,最后输出count值即可。
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c1=new CCircle(); //直接调用第一个构造函数
c1.show();
CCircle c2=new CCircle("yellow",2); //调用第二个构造函数
c2.show();
}
}
输出的结果为:
创建了1个对象
该圆的颜色: red,半径为: 1,面积为: 3.1415
创建了2个对象
该圆的颜色: yellow,半径为: 2,面积为: 12.566
static的使用不能以任何方式引用this和super。
static变量在类加载的时候,对象创建之前就已经被初始化.但是对象是在创建时才在内存中生成的。
而在方法中定义使用的this关键字指的就是对当前对象的引用.所以在static中使用this的话,this就无法指向合适的对象.
static和非static的区别:
1>static定义的函数,外部程序可以直接调用通过类名.函数名([参数])调用,但非static方法则必须通过创建对象后通过对象名.函数名([参数])的方法调用.
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
public static void perimeter()
{
System.out.println("圆");
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c1=new CCircle();
c1.show(); //非static通过类名.函数名的方法调用
CCircle c2=new CCircle("yellow",2);
c2.show();
CCircle.perimeter();//static定义的方法可以直接用类名.函数名的方法调用
}
}
2>类的内部,static的方法不能调用非static的方法,但是非static的方法可以调用static的方法.
上例中若是将perimeter()中的内容改成:
public static void perimeter()
{ System.out.println("圆");
System.out.println("该圆的面积为: "+area());
}
就会出现编译错误:
Cannot make a static reference to the non-static method area() from the type CCircle.
无法在静态方法中调用非静态方法area()。
上例中调用area()就相当于调用this.area(),而static中不能以任何方式调用this。所以不能调用非static的方法
3>static方法不能使用成员变量(同理,调用成员变量=this.成员变量,但static中不能含this).而非static方法中可以调用static 的变量.因为static的变量是在可以类中共享的。
同样将perimeter中的内容改成:
public static void perimeter()
{ System.out.println("圆");
System.out.println("该圆的颜色为: "+color);
}
也会出现编译错误。
如果一个类中没有定义成员变量,那么尽量将该方法定义为static方法。
对于main()它也是类method1(文件名)的一个函数,调用mian()的是类method1,而不是method1所创建的对象.因为main()是一个java程序的入口程序,所以在jvm调用
main()的时候希望能够直接调用main(),而不是再创建一个新的对象来调用main(),所以main的修饰符为static,这样jvm就能直接调用main()。
因此,在文件名所创建的类定义的成员变量最好使用static。这个时候就可以在main中直接调用。
import java.util.Scanner;
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
public static void perimeter()
{
System.out.println("圆");
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
static Scanner input=new Scanner(System.in);
public static void main(String args[])
{
CCircle c1=new CCircle();
c1.show();
CCircle c2=new CCircle("yellow",2);
c2.show();
CCircle.perimeter();
String s=input.next();
int r=input.nextInt();
CCircle c3=new CCircle(s,r);
c3.show();
}
}
运行结果为:
创建了1个对象
该圆的颜色: red,半径为: 1,面积为: 3.1415
创建了2个对象
该圆的颜色: yellow,半径为: 2,面积为: 12.566
圆
blue 3
创建了3个对象
该圆的颜色: blue,半径为: 3,面积为: 28.2735
当然不定义static也行,直接在main中创建一个新的对象再调用即可。
import java.util.Scanner;
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
/**
* 求该圆的面积
*/
public double area()
{
return pi*radius*radius;
}
public static void perimeter()
{
System.out.println("圆");
}
/**
* 显示该圆的基本信息
*/
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
Scanner input=new Scanner(System.in);
public static void main(String args[])
{
CCircle c1=new CCircle();
c1.show();
CCircle c2=new CCircle("yellow",2);
c2.show();
CCircle.perimeter();
method1 m=new method1();
String s=m.input.next();
int r=m.input.nextInt();
CCircle c3=new CCircle(s,r);
c3.show();
}
}
在static方法中可以通过创建一个新的对象来调用非static成员变量及方法。但貌似没这个必要。。
static变量尽量不要在构造函数中进行初始化,不然每次创建一个新的对象static的值又会被初始化。
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
count=0;
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
public double area()
{
return pi*radius*radius;
}
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c1=new CCircle();
c1.show();
CCircle c2=new CCircle();
c2.show();
}
}
编译运行后结果为:
创建了1个对象
该圆的颜色: red,半径为: 1,面积为: 3.1415
创建了1个对象
该圆的颜色: red,半径为: 1,面积为: 3.1415
static初始化:
1>可以直接在定义时赋值;
2>当变量较多时,可以放在static静态代码块中进行初始化.
class CCircle{
private String color; //将颜色定义为私有类型的成员变量,表示在类的外部不能改变其值
private double pi=3.1415;
private int radius;
private static int count;
static{
count=0;
}
public CCircle()
{
this("red",1); //调用下面的构造函数,this必须放在构造函数的第一行!!
}
public CCircle(String color,int radius)
{
this.color=color;
this.radius=radius;
count++;
System.out.println("创建了"+count+"个对象");
}
public double area()
{
return pi*radius*radius;
}
public void show()
{
System.out.println("该圆的颜色: "+color+",半径为: "+radius+",面积为: "+area());
}
}
public class method1 {
public static void main(String args[])
{
CCircle c1=new CCircle();
c1.show();
CCircle c2=new CCircle();
c2.show();
}
}