1.什么时候将一个变量定义为成员变量呢?
这个变量能够描述这个类的属性(现实真实事物的真实属性)----->将变量---->成员变量 (类中方法外) 随着方法调用结束而消失,所以内存角度考虑,比较节省内存空间!
2.面试题
2.1 Student s = new Student() ;完成了哪些事情
初始化过程: 1)在栈内存中开辟空间 Student s,变量s开辟 2)new Student(),需要在堆内存中申请空间 3)在申请空间的同时,需要对成员变量,进行默认初始化(根据数据类型进行默认赋值) 4)当默认初始化完毕,申请空间完毕,产生堆内存空间地址 5)通过构造方法初始化 6)将堆内存空间地址值赋值给栈内存的变量s 7)栈内存的变量s指向堆内存地址 8)当对象整个完毕之后,等待垃圾回收器空闲时候回收不用的对象...
2.2静态变量和成员变量的区别
(1)数据储存区域的区别: 静态变量:存储在方法区中的共享内存区域的静态区域中(static区域中); 成员变量:在堆内存中; (2)别名不同 静态变量:跟类有关系(类加载,静态的东西先进内存)----->"类成员" 成员变量:对象的特有属性------>"实例变量" (3)生命周期不用 静态变量:随着类的加载而加载,随着类的加载完毕,进入static区域中,消失了. 成员变量:随着对象的创建而存在,随着对象的创建完毕,等到垃圾回收器空闲时 间回收. (4)调用方式不同 静态变量:既可以使用对象名访问,也可以使用类名访问,推荐使用类名访问; 成员变量:只能使用对象名来访问.
3.继承
3.1 定义:将多个类的共性内容抽取到一个独立的类中,让这多个类和这个独立的类产生一种关系---"继承" extens; 格式: class Fu{ ....... } class Zi extends Fu{} 3.2 好处: (1)提高了代码的复用性; (2)提高了代码的维护性; (3)类与类产生的关系,是多态的前提条件. 3.3 弊端: 类与类之间产生了关系,就存在了耦合性; 开发的设计原则: 遵循"低耦合,高内聚" 3.4特点: (1)在java语言中,类与类之间的继承关系,只支持单继承,不支持多继承. (2)支持多层继承. 注意事项: (1)子类继承父类,只能继承父类非私有成员,私有的成员可以间接通过公共访问访问, 因为私有成员,只能在本类中被访问,外界不能访问; (2)子类继承父类,不能继承父类的构造方法,但是可以通过super访问. 3.5子父的继承关系中,成员变量的访问问题: 情况1: 子类继承父类,子类的成员变量名称和父类的成员变量名称不一致的情况:很简单,分别调用即可! 情况2: 子类继承父类,子类的成员变量名称和父类的成员变量名称一致的情况: 一句话:遵循 "就近原则" 1)现在子类的局部位置中找,如果存在,就使用 2)如果不存在,那么就在子类的成员位置中找,如果存在,就使用 3)如果子类的成员位置中不存在,那么就在父类的成员位置中找,如果存在,就使用; 4)如果父类的成员位置中不存在,那么就报错了,压根不存在这个变量 举例:class Fu{ //父类的成员变量 int num = 100 ; } class Zi extends Fu2{ //子类的成员变量名称和父类的成员变量名称一致 int num = 200 ; //子类的成员变量名称和父类的成员变量名称不一致 int num2 = 200 ; public void show(){ int num = 30 ; System.out.println(num) ; // System.out.println(num2); } } public class ExtendsDemo2 { public static void main(String[] args) { //情况1: Zi zi = new Zi() ; System.out.println(zi.num); System.out.println(zi.num2); System.out.println("-----------------------------------"); zi //情况2: Zi zi = new Zi() ; zi.show() ; } }
3.6继承中的构造方法的访问问题: 子类继承父类,不能继承父类的构造方法,但是可以通过super访问(super重点关键字) 如何访问: 子类的所有构造方法都要(默认)访问父类的无参构造方法 因为存在继承关系,子类的构造方法可能会用到父类的数据,所以需要让父类先 初始化(构造方法),然后子类在进行初始化 -- -->分层初始化 在子类的所有构造方法中第一句话:super() ; 访问父类的无参构造方法 3.7面试题 子类继承父类,如果父类的无参构造方法没有提供,仅仅提供父类的有参构造方法,子类会出现什么现象,如何解决呢? 子类的所有构造方法都会报错,原因就是没有父类的无参构造方法, 子类的所有构造方法默认访问父类的无参构造方法(super();) 解决方案: 1)最简单的方式:给父类提供出无参构造方法 2)现在不想让你父类的无参构造方法 可以让子类的所有构造方法直接访问父类的有参方法... 3)很少用到: 方式3: 先通过子类的有参构造方法,访问本类的无参构造方法 this() 然后通过本类的无参构造方法,访问父类的有参构造方法,让其初始化(子类的所有构造方法只要一个能够让父类初始化) 举例:class Fu2{ public Fu2(){ System.out.println("这是父类的无参构造方法..."); } public Fu2(String name){ System.out.println("Fu2的有参构造方法..."); } } class Zi2 extends Fu2{ //子类的无参构造方法 public Zi2(){ super("随便给") ; System.out.println("Zi2的无参构造方法..."); } public Zi2(String name){ //super("随便给") ; //方式3: this() ; //访问当前类的无参构造方法 System.out.println("Zi2的有参构造方法..."); } } public class ExtendsDemo2 { public static void main(String[] args) { Zi2 zi = new Zi2() ; Zi2 zi2 = new Zi2("helloworld") ; } }
3.8方法重写 子类继承父类的时候,子类的出现了 和父类一模一样的方法声明,这个子类的功能将父类的功能覆盖掉,使用自己的业务功能完成! 英文单词:override 方法重载:overload:多个方法名相同,形式参数列表不同,与返回值无关,目的:为了提高功能扩展! 方法重写(覆盖/复写):override:子类继承父类的时候,子类的出现了 和父类一模一样的方法声明 目的:使用子类的功能,将父类的功能覆盖掉.
举例:
class Phone{
public void call(){
System.out.println("手机可以打电话了...");
}
}
class NewPhone extends Phone{
//call
public void call(){
super.call() ;
System.out.println("手机可以看天气预报了") ;
System.out.println("手机还可以微信聊天了...") ;
}
}
public class ExtendsDemo {
public static void main(String[] args) {
NewPhone np = new NewPhone() ;
np.call() ;
}
}
4.static关键字以及它的特点
1.概念: 共享,共用(可以被多个对象共用);被静态修饰的东西是随着类的加载而加载. 2.特点: (1)被静态修饰的变量/方法,都是随着类的加载而加载. (2)优先于对象存在,不能和this关键字共存,this是需要等待对象被创建完毕,而被静态修饰的,优先进入了static内存区了. (3)共享,共用(可以被多个对象共用) (4)被静态修饰的变量/方法,推荐使用类名访问. 静态成员变量: 类名.变量名; 静态成员方法: 类名.方法名; 3.静态使用注意事项: (1)非静态的成员方法,可以访问静态的成员变量或者是非静态的成员变量; (2)静态的成员方法: 静态只能访问静态.
举例:
class Demo{
//非静态的成员变量
int num = 10 ;
//静态的成员变量--------随着的类的加载而加载: "类成员"
static int num2 = 200 ;
//非静态的成员方法
public void show(){
System.out.println("show demo ...");
}
//静态的方法
public static void method(){
System.out.println("method demo...");
}
}
//测试类
public class StaticDemo2 {
public static void main(String[] args) {
//访问num这个变量
Demo d = new Demo() ;
System.out.println(d.num); //非静态的成员变量("对象变量")
// System.out.println(d.num2); //可以访问,不推荐这样使用 ("类成员",类名来访问)
System.out.println("----------------------------------------");
System.out.println(Demo.num2);
System.out.println("----------------------------------------");
//访问show()方法,非静态的
d.show();
//访问method()方法,静态方法
Demo.method();
//一般情况:静态的使用:都是在工具类中:工具类中的所有的方法都会提供 静态的,为了访问方便
double result = Math.random();//random()方法就是静态的
System.out.println(result);
}
}
5.final关键字
定义: final:最终的,无法更改的(状态修饰符) 特点: 1)可以修饰类,该类不能被继承,它不能在进行扩展了... 举例:后面常用类中重要的类String: 被final修饰 2)可以修饰变量,此时这个变量是一个常量:自定义常量 3)可以修饰成员方法,此时这个方法不能被重写. 应用场景 自定义常量使用居多; final会结合static一块使用(static修饰:可以类名直接调用) public static final int num = 100 ; //修饰基本数据类型 :编译时期常量 (Jvm不需要加载) //Integer:int类型的包装类类型(引用类型) public static final Integer i = new Integer() ;//修饰的引用数据类型 :运行时期常量(JVM需要加载类) 面试题: final修饰的基本数据类型和修饰引用数据类型的区别? 修饰的基本数据类型:基本数据类型的值不能在改变,只能赋值一次,此时这种常量,称为"编译时期常量",Jvm只是检查语法,不需要加载的! 修饰的引用数据类型:引用数据类型的空间地址值不能在改变,但是里面的成员变量(没有加入final),依然可以方法.这种常量,Jvm加载引用数据类型,属于 开发中使用最多的: 就是修饰基本数据类型: 传统方式的自定义常量 public static final 基本数据类型 变量名 = 常量值 ; JDK5以后:枚举类 Enum :定义常量