1.构造函数的作用:
实现属性的初始化
使用构造函数实现成员变量的初始化
非静态成员变量 随着对象的常见才开辟空间,所以只能使用对象来访问
静态成员变量,随着类的加载而开辟空间,可以通过类直接访问
2.static关键字:
static修饰成员变量的特点:
1:static修饰的成员变量是随着类的加载而在方法区中的静态区开辟内存的
2:static修饰的成员变量是其所属类的所有对象共享的
3:static修饰的成员变量可以通过类直接访问,也可以通过对象访问
缺点:占用内存时间太长(static修饰的变量存储在方法区的静态区中,直到程序结束才会释放内存)
3.非静态的方法:静态的和非静态的都能用
静态的先出现,非静态的后出现,静态的只能用静态的
静态的优先于非静态的开辟内存
4.静态成员变量和非静态成员变量对比:
1: 访问方式
静态成员变量可以通过类名访问,也可以通过对象访问
非静态成员变量只能通过对象来访问
2:存储位置
静态成员变量是随着类的加载在方法区的静态区中开辟内存
非静态成员变量是随着对象的创建在堆中开辟内存
3:存储数据
静态成员变量存储的是其所属类的所有对象共享的数据
非静态成员变量存储的是其所属类的每个对象特有的数据
4:生命周期
静态成员变量是随着类的加载在方法区的静态区中开辟内存,程序退出时才释放内存
非静态成员变量是随着对象的创建在堆中开辟内存,当对象被垃圾回收时才释放内存
1 class Student 2 { 3 String name; //非静态成员变量 随着对象的创建才开辟内存,所以只能使用对象来访问 4 static String country="CN"; //静态成员变量,随着类的加载而开辟内存,可以通过类直接访问 5 //非静态方法:静态和非静态的都能使用 6 public void study(){ 7 System.out.println("好好学习,天天向上"+name+","+country); 8 } 9 10 public static void show()//静态方法 Student.show(); 静态的先出现,非静态的后出现,静态的只能使用静态的 11 { 12 System.out.println("万元户"+name);//无法从静态上下文中引用非静态变量 13 } 14 }
1 public static void main(String[] args) 2 public :公共的 3 static:静态成员变量是随着类的加载在方法区的静态区中开辟内存,程序退出时才释放内存 4 void:说明该方法无返回值 5 String[] args:main方法的参数是一个字符串数组
main函数可以重载,只有public static void main(String[] args) 这样的JVM才会识别为程序的入口,从而进入程序
由静态可以通过类名调用,通过类名访问可知,程序入口main()函数定义为static的原因为JVM直接调用类名.main自动运行程序
5.static 只能修饰成员变量、成员方法、内部类
1.什么情况下使用static?
什么情况下需要把成员变量修饰为static?
当该成员变量的值需要被所有对象共享时,该变量的值在内存中只有一份
什么情况下需要把成员方法修饰为static?
当该方法没有用到所在类的任何非静态成员,因为静态的只能用静态的,只要方法用到了非静态的就不能被修饰为static
6.内存:静态成员变量是随着字节码文件的加载加载到在方法区的静态区中开辟内存,程序退出时才释放内存
所以可以直接通过类名访问
1 class Person 2 { 3 int age; 4 static String country="CN"; 5 6 Person(){} 7 8 Person(int age){ 9 this.age=age; 10 } 11 12 public static void show(Person person)//没有用到本类中的非静态成员变量,用到的是新的对象中的age属性,和当前的show方法不是一个类中,所以可以是static的 13 { 14 System.out.println(person.age); 15 } 16 17 public static int add(int a,int b) 18 { 19 return a+b; 20 } 21 }
7.静态(static)的应用:工具类
让类不能new对象,为了实现禁止创建对象
实现:private Array(){};//自定义构造方法,并且用private修饰
8.javadoc -d doc Array.java
//生成api(说明书)-d(路径)doc(文件目录) Array.java(要生成api的java源程序)
//类必须用public修饰
9.自定义的class类中定义的属性,即成员变量,在堆中开辟内存空间,有默认值
局部变量,在栈中开辟内存空间,没有默认值,一般需要手动初始化
静态代码块:随着类的加载而执行,只执行一次,因为.class文件只加载一次,优先于main的执行
1 class A 2 { 3 static int num=10; 4 static 5 { 6 System.out.println(num); 7 //静态代码块 8 } 9 }
作用:可以把程序的初始化功能写在静态代码块中,随着类的加载就同时执行了
应用场景1:对数据库的连接操作可以写进静态代码块中
10.构造代码块:对象一创建就执行,优先于构造函数
作用:构造代码块用于定义所有对象共同的行为
1 class Person 2 { 3 String name; 4 int age; 5 { 6 System.out.println("哈哈"); 7 } 8 Person(String name,int age) 9 { 10 this.name=name; 11 this.age=age; 12 } 13 }
11.对象初始化过程:
1.因为创建对象需要字节码,所以先加载Person.class到方法区
2.如果有静态代码块执行静态代码块
3.到堆中开辟内存
4.给成员变量赋默认值
5.如果有初始值,给成员变量赋初始值
6.执行构造代码块
7.执行构造函数
8.把对象在堆中的内存地址赋给栈中变量
12.单例设计模式:解决的是让一个类在内存中只能有一个对象
1.要想让一个类只有一个对象,首先这个类肯定不能new
2. 构造方法修饰为private,那么一个对象都没有了,只能在本类中创建对象
3.需要把这个对象提供给外界使用
(外部不能new,不能创建对象,但是在内部能new,能创建自己类型的成员的变量)
1 单例模式-------饿汉式(实际中使用) 2 class Earth 3 { 4 private static Earth earth=new Earth();/*Earth类型的成员变量,这里不能修饰为public,因为如果是public,则可以Earth.diqiu调用,但是如果 Earth.diqiu=null,则没有对象了,不安全*/ 5 private Earth(){}; 6 //让外界得到内部创建的对象 7 public static Earth getIntet() 8 { 9 return earth; 10 } 11 }
1 单例模式-------懒汉式(多线程中容易出现线程安全问题) 2 class Earth 3 { 4 private static Earth earth=null; 5 private Earth(){}; 6 //让外界得到内部创建的对象 7 public static Earth getIntet()//只有在初始化的时候才new对象 8 { 9 if (earth==null) 10 { 11 earth=new Earth(); 12 } 13 return earth; 14 } 15 }
13.继承:实现了代码的重复使用,使类和类之间产生了关系,被继承的是父类,继承的是子类
单继承:java中的继承是单继承的,一个类只能继承另外一个类
多继承:一个类能继承多个类(多继承会出现调用的不确定性)
方法:提取共同的属性和行为,封装到一个类中
1 class A 2 { 3 public void show(){ 4 System.out.println("A"); 5 } 6 } 7 class B 8 { 9 public void show(){ 10 System.out.println("B"); 11 } 12 } 13 class C extends A,B{ 14 15 } 16 public static void main(String[] args) 17 { 18 C c = new C(); 19 c.show(); //多继承会出现调用的不确定性 20 }
14.java支持多层继承
class D(){}
class E extends D(){}
class F extends E(){}
15.继承中成员变量的特点:
this:是一个引用,总是指向当前被使用的对象
super:不是引用,代表的是父类的数据空间,当子父类中出现同名现象时用来进行区分的
//具备相同的行为,只是行为的表现方式不同
//重写,覆盖
16重写:子类和父类中出现了相同的方法,这种现象叫重写,也叫覆盖
当创建子类对象并调用重写的方法时,执行的肯定是重写以后的方法
1.子类在重写时,方法的权限必须大于等于父类中方法的权限
2.private修饰的方法不能被重写
3.父类中的方法是静态的,子类重写时也必须是静态的