1、构造方法
1)构造方法的语法
public class Deom{
private int a;
public static void main(String[] args) {
new Demo();
}
//无参的构造方法
public Deom(){
System.out.println("无参的构造方法被调用!!");
}
//带参的构造方法 相当于构造方法重载
public Demo(int a){
this.a=a;
System.out.println("带参的构造方法被调用!!");
}
}
2)每个类都隐式自带一个无参的构造方法,当我们new一个实例时,JVM就会默认调用这个无参的构造方法。需要注意的是构造方法是可以被重载的,当我们显式重载了一个构造方法时,自带的隐式无参构造方法就会消失,所以,我们一般都显式的将无参的构造方法写出来。
3)构造方法如何被调用?
上面说到构造方法是在new实例时JVM自动调用,在普通方法中无法被调用,除了JVM调用之外,我们还可以在其他重载的构造方法中调用另一个构造方法,调用时不是使用方法名进行调用而是使用this关键字进行调用,this代表当前类的引用。
public class Deom{
private int a;
public static void main(String[] args) {
new Demo();
}
//无参的构造方法
public Deom(){
this(6);//调用下面带参的构造函数
System.out.println("无参的构造方法被调用!!");
}
//带参的构造方法 相当于构造方法重载
public Demo(int a){
this.a=a;
System.out.println("带参的构造方法被调用!!");
}
}
上面代码可以看出,JVM在调用无参的构造方法后,无参的构造方法中又使用this调用了下面的带参的构造方法,带参的构造方法中将这个类的实例给初始化了。
4)关于构造方法的修饰符问题
如果一个类中的构造方法全部私有了(被private修饰),那在类的外部是不可以产生该类的实例的。
2、static 关键字
1)为什么会有static关键字?
这个关键字可以修饰成员变量,成员方法,用这个关键字修饰之后的成员会存储在JAVA内存中的静态方法区中,也就是说所有new的对象都共享这块内存(节省内存)。
注意: static 不能修饰局部变量
2)static修饰成员变量
当一个类中的所有对象的某个属性的值都一样的话,那么我们常常把这个属性用static来修饰。
如果static修饰一个成员变量后,我们就需要在类中就给这个成员变量初始化,那以后在其他地方new这个类的实例的时候就不需要给这个变量初始化了。因为所有new的实例都会去静态方法区中找到这个变量的值,这样节省了内存(如果没用static修改,那这个变量就不会出现在静态方法区中,而是跟着new实例的时候放在栈内存中,每new一个实例堆内存中就会存一遍这个变量,浪费内存)。
3)static修饰成员方法
当一个成员方法中没有使用到非静态成员变量的话,就可以使用static来修饰这个方法。
注意: 静态方法中不能使用非静态的成员(静态的先于非静态加载,如果非静态成员还没初始化就尴尬了)
4)静态成员变量与静态成员方法的调用
a 跟非静态的调用方法一样
b 通过类名直接调用
package cn.com.kingc.eoms.controller;
public class Ceshi {
public int a;
public static String str;
public static void sleep(){
System.out.println("正在睡觉............");
}
}
class OtherClass{
public static void main(String[] args) {
//直接使用类名调用
Ceshi.sleep();
//普通方法调用
Ceshi ce=new Ceshi();
ce.sleep();
}
}
5)静态成员变量与非静态成员变量的区别?
a.存储区域
静态成员变量---》 静态方法区
非静态成员变量--》 堆内存
b. 生命周期
静态成员变量--》类加载时开始初始化,类卸载时进行消毁。
非静态成员变量--》在堆内存中为对象开辟空间时开始进行初始化,当没有引用指向对象时,此时垃圾回收器会把非静态成员变量的内存空间消毁。
c.调用方式
静态成员变量-》可以通过类名,对象名来调用
非静态成员变量-》只能通过对象名来调用
3、静态代码块
1)为什么会有静态代码块
对象初始化(对对象中的非静态成员进行初始化)使用的方法是构造方法,如果对类进行初始化(对象中的静态成员的初始化)那么该怎么办?这里用到静态代码块
2)什么叫对类进行初始化
类的初始化的意思是对类中的静态成员进行附值。
对象的初始化的意思是对类中非静态成员进行的附值。 new完产生对象后才能用构造方法对非静态成员进行赋值
3)静态代码块的使用如下图:直接在声明静态变量的时候初始化跟使用静态代码块初始化是一样的
package cn.com.kingc.eoms.controller;
public class Ceshi {
public static int a;
public static String str;
static {
a=1;
str="哈哈";
}
}
class OtherClass{
public static void main(String[] args) {
//调用类中的静态成员变量,查看值
String str = Ceshi.str;
System.out.println(str);
}
}
4、final 关键字
1)final 修饰的类 不能被继承
2)final 修饰的方法不能被覆写(重写),可以重载(参数个数、类型不同)
3)final 修饰的变量会变成常量,也就是说在声明这个变量的时候就要将这个变量初始化,并且该值不能被修改
注意:一般来说用final修饰的变量,它的变量名字一般都要全部大写
5、extends 继承关键字
1)使用extends关键字来继承一个父类
package cn.com.kingc.eoms.controller;
public class Person {
public String sex;
public String name;
public Person(){
System.out.println("调用父类构造函数!!!!!!!!!");
}
}
class Worker extends Person{
public Worker(){
super();//默认隐式调用父类的无参的构造函数,要放在第一句,super()本身可以传参
System.out.println("调用子类构造函数!!!!");
}
}
class Ceshi{
public static void main(String[] args) {
Worker worker=new Worker();
}
}
2)父类与子类变量覆盖问题
当父类中的变量与子类中的变量一样时,会取子类中的变量值(包括静态与非静态)
3)当父类方法逻辑不满足子类需求时,我们需要在子类中进行方法的复写,被复写的方法上要加@Override注解
6、abstract 抽象类关键字(说白了一个抽象类就是用来被继承的,继承之后我们要重写里面抽象方法)
1)语法格式
public abstract class Person{
//抽象类中的抽象方法用abstract 修饰
public abstract void run();
//抽象类中可以有具体方法
public void eat(){
System.out.println("正在吃饭...............");
}
}
2) 抽象类的注意事项:
声明抽象类时,不需要权限修饰符修饰(public 、private)
1)一个类中如果有抽象方法,那么这个类必须是抽象类,抽象类中可以有具体方法和抽象方法。
2)一个类如果继承了一个抽象类,那么这个类必须实现抽象类中的抽象方法,如果不实现那么这个类也必须是抽象类。
3)抽象类不可以产生对象。
4)抽象类中可以有构造方法。
5)抽象类不能new出对象
6)抽象方法不能使用 private、static、final修饰。因为抽象方法就是要被继承重写的
7)抽象类不能被 final修饰,因为抽象类就是要被继承的
7、interface 接口关键字
1)当一个抽象类中的方法全是抽象方法时,我们就不能把这个类叫抽象类了,而应该叫接口
2)语法格式
//这个是接口的定义,注意定义的时候class关键字不需要写
public interface Person{
//接口中的成员变量默认被public static final修饰,所以可以这样定义变量
int NUM=78;
//显式定义变量如下
public static final String SXE="男";
//抽象方法
public abstract void run();
//抽象方法
public void eat();
//在接口中抽象方法默认被 public adstract 关键字修饰,所以可以写成如下格式
void sleep();
}
3)类和抽象类都可以被继承,且子类只能单继承。而接口是用来实现的,并且可以多实现,请看8
8、implements 实现接口的关键字
package cn.com.kingc.eoms.controller;
//接口1
public interface Person{
public abstract void run();
public void eat();
void sleep();
}
//接口2
interface Person1{
public void eat1();
}
//接口3可以多继承其他接口
interface Person2 extends Person,Person1{
public abstract void run2();
}
//普通类可以多实现接口,并必须要实现接口中的所有方法
class Ceshi implements Person,Person1,Person2{
@Override
public void run() {
}
@Override
public void eat() {
}
@Override
public void sleep() {
}
@Override
public void eat1() {
}
@Override
public void run2() {
}
}