一. 构造方法
1.构造方法的作用?
构造方法作用就是对对象的属性(成员变量)进行初始化
2.写法:
1.构造方法的名与类名完全相同(大小写必须一样)
2.没有返回值类型(连void都不写)
3.没有返回值(没有return)
代码实现:
class Car { //车的类
String name; // 车的名字
String type; // 车的类型
public Car(){
}
}
我们知道,java语言中规定每个类至少要有一个构造方法,为了保证这一点,当用户没有给java类定义明确的构造方法的时候,java为我们提供了一个默认的构造方法,这个构造方法没有参数,修饰符是public并且方法体为空
在我们创建对象的时候 ,new一个对象的时候要用到构造函数,这时系统会给你自动调用一个无参的构造方法(也就是系统给我们提供默认的构造方法)
实现代码:
Hello hello = new Hello();这时调用的是Hello的无参数构造方法;
// public Hello(){} // 系统默认的无参构造方法
如果Hello类中已经有了一个有参数的构造方法,这时再使用 Hello hello = new Hello();来创建对象的时候就会出错, 所以构造方法分为两种,一种就是刚刚说过的隐藏的构造方法,另一种就是显示定义的构造方法.
如果一个类中定义了一个或者多个构造方法,并且每一个构造方法都是带有参数形式的,那么这个类就没有默认的构造方法,看下面的例子。
public class Sample1{ // 样品类
}
public class Sample2{
public Sample2(int a){ // 有参构造方法
System.out.println("My Constructor");
}
}
public class Sample3{
public Sample3(){ // 无参构造方法
System.out.println("My Default Constructor");
}
}
上面的三个类中Sample1有一个隐式的默认构造方法,下列语句Sample1 s1=new Sample()合法;
Sample2没有默认的构造方法,下列语句Sample2 s2=new Sample2()不合法,执行会编译错误
Sample3有一个显示的默认构造方法,所以以下语句Sample3 s3=new Sample3();合法
3.构造方法的注意事项
1.如果你没写任何构造方法
那么系统会给你提供一个 无参的构造方法
2.如果你写了一个有参的构造方法
这时系统就不在对你提供 无参的构造犯法
3.如果你想写有参构造方法 建议你把无参的构造方法也写上
实现代码:
public static void main(String[] args) {
Car c1 = new Car("奇瑞",4);
// 这样修改对象的属性 属于谋杀
// 坏处: 浪费内存空间
c1 = new Car("宝马",4);
// 直接对象点属性修改 相对于上面的方法 更灵活 省空间
c1.name = "奥迪";
c1.num = 100;
c1.sayHi();
}
}
class Car{
String name;
int num;
// 不管你写不写有参的 都要把无参的都写上
public Car() {
}
// 写个有参的构造方法
public Car(String name,int num){
this.name = name;
this.num = num;
}
// 函数的重载 参数不同(顺序 个数 参数类型)
// 切记 参数的名字不同 不是函数的重载
// 构造方法也符合 函数的重载
public Car(String name) {
this.name = name;
}
public void sayHi() {
System.out.println(name + "--" + num);
}
}
4.构造方法的总结
1、和成员方法(实例方法)一样,构造方法可以有任何访问的修饰符,public、private、protected或者没有修饰符 ,都可以对构造方法进行修饰。
2、返回类型是非常重要的,实例方法可以返回任何类型的值或者是无返回值(void),而构造方法是没有返回类型的,void也不行。
3、至于命名就是构造方法与类名相同,当然了实例方法也可以与类名相同,但是习惯上我们为实例方法命名的时候通常是小写的,另一方面也是与构造方法区分开。
而构造方法与类名相同,便于观察理解
4.构造方法可以重载,以参数的个数,类型,或排序顺序区分。
5.以后在写构造方法的时候,不管你写不写有参的 都要把无参的都写上
6.想修改对象的属性的话,直接对象点属性修改 更灵活 省空间
public class Sample {
private int x;
public Sample() { // 不带参数的构造方法
}
public Sample(int x) { //带参数的构造方法
this.x=x;
}
}
二.static关键字
1.static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法
public class Test5 {
static int a; // static修饰
int b;
public static void test(){ // static修饰
System.out.println(a + "--" + b);
}
2.被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。
如何实现的?
只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
静态变量要用类名去调用
静态变量不依赖类 因为静态变量被加载的时候 对象还没有创建
tatic修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:
类名.静态方法名(参数列表...)
类名.静态变量名
3.静态变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量;另一种是没有被static修饰的变量,叫成员(实例)变量。
两者的区别是:
对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)
对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝
内存表现步骤
1.类加载到方法区
2.加载到方法区的同时 静态变量被加载到方法区 静态区
3.main入栈
4.在堆内存中创建 对象
5.把地址赋值给main函数的对象
6.程序结束 (出栈)个功能时使用静态变量:
5.什么时候用呢?
在对象之间共享值时
方便访问变量时
6.静态变量和成员变量的区别?
1.所属不同
成员变量: 成员变量属于对象的 对象变量 (实例变量)
静态变量: 属于类的 又叫类变量
2.内存中的存储位置不同
成员变量:存储在堆内存
静态变量:存储在方法区的静态区中
3.加载到内存中的时机不同(声明周期)
成员变量:随着对象的创建而创建
静态变量:随着类的加载而存在
4.调用方法不同
成员变量:只能使用对象去调用
静态变量:可以用对象去调用 但是一般用类名去调用
7.静态变量特点 好处 应用场景 与成员变量的区别?
静态变量特点:
1.随着类的加载而加载
一旦static被创建,它会一直存在静态常量池中,知道程序执行完,随着类的消失而消失,它的生命周期相对来说是最长的
2.创建优先于对象存在
静态是优先于对象存在的。
3.是类创建出来的对象 (共享)共有的部分
因此,静态的成员变量和方法也不能使用this,super关键字,这2个关键字都是基于对象的。
4.可以使用类名去调用
好处:节省内存空间
应用场景:
饮水机 和 水杯
8.静态方法 (类方法)
静态方法可以直接通过类名调用,任何的实例也都可以调用
声明一个 静态成员方法
静态的成员方法中 不能使用 成员变量
只能使用静态变量
简单记法 : 静态的方法只能使用静态的变量 和静态方法
例如为了方便方法的调用,Java API中的Math类中所有的方法都是静态的,而一般类内部的static方法也是方便其它类对该方法的调用。
静态方法是类内部的一类特殊方法,只有在需要时才将对应的方法声明成静态的,一个类内部的方法一般都是非静态的
实现代码:
public class Demo {
public static void main(String[] args) {
Test.name="hello";
Test.sayHello();//优于对象创建,所以可以直接调用static修饰的方法
//Test.age=0 //调用非静态变量age会报错,因为对象还未创建
Test t=new Test();//创建对象
t.age=18;//这个时候就可以调用非静态变量和方法
t.hello();
}
}
class Test{
static String name; // 静态变量
int age; // 成员变量
public static void sayHello(){ // 静态方法
System.out.println("sayHello name:"+name);
}
public void hello(){ // 成员方法
System.out.println("hello age:"+age);
}
}