一、什么是构造方法?
普通方法用来定义对象的功能行为,构造方法用来初始化。
1.构造方法是类的一种特殊方法,用来初始化类的一个新的对象。
2.Java 中的每个类都有一个默认的构造方法,它必须具有和类名相同的名称,而且没有返回类型(不能使用return语句)。
3.构造方法的默认返回类型就是对象类型本身,并且构造方法不能被 static、final、synchronized、abstract 和 native 修饰。
提示:构造方法用于初始化一个新对象,所以用static修饰没有意义;因为构造方法不能被子类继承,所以用final和abstract修饰没有意义;多个线程不会同时创建内存地址相同的一个对象,所以用synchronized修饰没有意义;此外,java不支持mative类型的构造方法。
构造方法的语法格式:
class Class_name{ public Class_name(){ //默认无参构造函数 } public Class_name([paramList]){ //定义构造方法 } ... //类主体 }
在一个类中,与类名相同的方法就是构造方法。每个类可以具有多个构造方法,但要求它们各自包含不同的方法参数。
注意:类的构造方法不是要求必须定义的。如果在类中没有定义任何一个构造方法,则 Java 会自动为该类生成一个默认的构造方法。默认的构造方法不包含任何参数,并且方法体为空。如果类中显式地定义了一个或多个构造方法,则 Java 不再提供默认构造方法。
二、什么是静态属性和静态方法?
静态属性和静态方法都属于静态对象,由static修饰符修饰。与非静态属性的差别:
静态对象 | 非静态对象 | |
拥有属性 | 是类共同拥有的 | 是类各个对象独立拥有的 |
内存分配 | 内存空间上固定分配的 | 空间在各个附属类里面分配的 |
分配属性 | 先分配静态对象空间 | 继而再对非静态对象分配空间,即初始化 |
静态对象有什么好处?
1.静态对象的数据在全局中是唯一的。如果你想要处理的东西是整个程序中唯一的,写成静态是个好办法。非静态的东西修改了以后只是修改了他自己的数据,但是不会影响其他同类对象的数据。
2.引用方便。直接用 类名.静态方法 或者 类名、静态变量名 就可以直接修改器属性值,不用get()和set()方法。
3.保持数据的唯一性。此数据是全局唯一的,修改它的任何一个地方,在程序有使用到的地方都会体现出对这些数据的修改。有效提高效率。
4.static final用来修饰成员变量和成员方法,可以简单理解为"全局常量"。对于变量,表示一旦给定就不可修改,对于方法,表示不可覆盖(即重写)。
静态方法、静态变量和静态块
通常情况下,类成员必须通过它的类的对象访问。但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。
在成员的声明前面加上关键字static就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象(跟类是否有static修饰无关)。
你可以将方法和变量都声明为static。static 成员的最常见的 例子是main( ) 。声明为static的方法有以下几条限制:
A.它们仅能调用其他的static方法
B.他们只能访问static数据
C.它们不能以任何方式引用this或super(this涉及到对象, super与继承有关)
示例:Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块。
public class test{ static int a = 3; //静态变量 static int b; static void meth(int x){ //静态方法 System.out.println("x = "+x); System.out.println("a = "+a); System.out.println("b = "+b); } static { //静态代码块 System.out.println("static block initialized"); b = a*4; } public static void main(String[] args) { meth(42); } }
执行结果是:
上述示例代码的执行顺序是:先执行 static块,后执行static方法,再执行普通方法,最后执行构造方法。
首先static 块执行(打印一条消息),a被设置为3,最后b被初始化为a*4 成12。
然后调用main(),main () 调用meth() ,把值42传递给x。
3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。
外部使用静态变量或静态方法
在定义它们的类的外面,在定义它们的类的外面,static 方法和变量能独立于任何对象而被使用,你只要在类的名字后面加点号运算符即可。可以看到,这种格式与通过对象引用变量调用非static方法或者变量的格式类似。
示例:
class StaticDemo{ static int a = 42; static int b = 99; static void callme(){ System.out.println("a = "+a); } } public class test{ public static void main(String[] args) { StaticDemo.callme(); System.out.println("b = "+StaticDemo.b); } }
执行结果:
三、父类的静态方法能否被子类重写?
不能。
父类的静态方法能够被子类继承,但是不能够被子类重写,即使子类中的静态方法与父类中的静态方法完全一样,也是两个完全不同的方法。
所谓静态就是指:在编译之后所分配的内存会一直存在(不会被回收),直到程序退出内存才会释放这个空间。
因为静态方法从程序开始运行后就已经分配了内存,也就是说已经写死了。所有引用到该方法的对象(父类的对象也好子类的对象也好)所指向的都是同一块内存中的数据,也就是该静态方法。子类中如果定义了相同名称的静态方法,并不会重写,而应该是在内存中又分配了一块给子类的静态方法,没有重写这一说。
示例:
class Fruit{ static String color = "五颜六色"; static public void call(){ System.out.println("这是一个水果"); } } public class test extends Fruit{ static String color = "黄色"; static public void call(){ System.out.println("这是一个香蕉"); } public static void main(String[] args) { //注:调用静态对象直接类名.静态对象即可,这里实例化是为了说明能否被重写。 Fruit fruit = new test(); System.out.println(fruit.color); fruit.call(); } }
执行结果:
如代码所示,如果能够被重写,则输出的应该是"这是一个香蕉"。与此类似,静态变量也不能够被重写。如果想要调用父类的静态方法,应该使用类来调用。
四、静态属性和静态方法是否可以被继承?
可以被继承,如果子类中有相同的静态方法和静态变量,那么父类的方法以及变量就会被覆盖。要想调用就就必须使用父类来调用。
实例:子类不能通过继承重写父类的静态方法,但是可以隐藏父类的方法(相同于覆盖了)
class Fruit{ static String color = "五颜六色"; static String shape = "奇形怪状"; static public void call(){ System.out.println("这是一个水果"); } static public void test(){ System.out.println("这是没有被子类覆盖的方法"); } } public class Banana extends Fruit{ static String color = "黄色"; //覆盖 static public void call(){ System.out.println("这是一个香蕉"); } public static void main(String[] args) {
Banana banana = new Banana(); banana.test(); //调用了Fruit中的test方法 banana.call(); //覆盖了Fruit中的call方法 Fruit.call(); //直接调用静态方法 System.out.println(shape + " " + color); } }
执行结果:
从上述代码可以看出,子类中覆盖了父类的静态方法的话,调用的是子类的方法,这个时候要是还想调用父类的静态方法,应该是用父类直接调用。如果子类没有覆盖,则调用的是父类的方法。静态变量与此相似。