目录
1. 类变量和实例变量的区别2. 继承、多态易混点整理
3. 类的加载过程
4. 类变量和实例变量的区别
5. 类变量和实例变量的区别
6. 类变量和实例变量的区别
1.类变量和实例变量的区别
- 类变量也叫静态变量,也就是在变量前加了static 的变量;
- 实例变量也叫对象变量,即没加static 的变量;
类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
class person{
static String age; //--类变量
public String name="李四"; //--实例变量
}
public class ClassJava{
public static void main(String[] args){
person A=new person();
A.age="10";
A.name="张三";
System.out.println(A.age); //-结果为"10"
System.out.println(A.name); //-结果为"张三"
person B=new person();
//类变量是针对所有对象的,所以A改变age,B的age也改变
System.out.println(B.age); //-结果为"10"
//实例只改变自身的,所以A对象的name改变,不影响对象B的name变量
System.out.println(B.name); //-结果仍为"李四"
}
}
2.继承、多态易混点整理
- new的过程中,父类先进性初始化,子类可通过super调用父类相应的构造方法,没有使用super的情况下,调用父类的默认构造方法。
- 子类变量和方法与父类重名情况下,可通过super强制访问父类的变量和方法
- 子类对象可以赋值给父类引用变量,这叫多态;实际执行调用的是子类实现,这叫动态绑定
2.1父类与子类变量名相同情况小栗子如下
class Person{
int age = 1;
Person(){
test();
}
public void test(){
}
}
public class Man extends Person{
int age = 1;
public void test(){
System.out.println("age = "+age);
}
public static void main(String args[]){
Man men=new Man();
men.test();
}
}
第一次输出0,第二次输出123。
第一次输出是在new过程输出的,在new过程中,首先是初始化父类,父类构造方法调用test()方法,test()方法被子类重写,就会调用子类的test()方法,子类方法访问子类实例变量a,而这个时候子类的实例变量的赋值语句和构造方法还没有执行,所以输出的默认值0
2.2子类拥有和父类同名的属性和方法时
class Base {
public static String s = "static_base";
public String m = "base";
public static void test() {
System.out.println("base static: " + s);
}
}
/**
- 子类定义和父类重名的变量和方法
- @author XXX
*/
public class Child extends Base {
public static String s = "child_base";
public String m = "child";
public static void test() {
System.out.println("child static: " + s);
}
public static void main(String args[]) {
Child c = new Child();
System.out.println(c.s);
System.out.println(c.m);
c.test();
Base b = c;
System.out.println(b.s);
System.out.println(b.m);
b.test();
}
}
子类定义了和父类重名的变量和方法。对于一个子类对象,他就有了两份变量和方法,在子类内部访问的时候,访问的是子类的,或者说,子类变量屏蔽了父类对应的变量和方法。
当通过b(静态类型Base)访问时,访问的是Base的变量和方法。
当通过c(静态类型Child)访问时,访问的是Child的变量和方法。这称之为“静态绑定”,即访问绑定到变量的静态类型
静态绑定在程序编译阶段即可决定,而动态绑定则要等到程序运行时,实例变量、静态变量、静态方法、private方法都是静态绑定的
2.3重载和重写
- 重载 :方法名相同,参数列表不同
- 重写:子类重写父类方法(子类方法不能降低父类方法可见性,可一致也可升级)
当有多个重名函数时,在决定调用哪个函数过程中,首先按照参数类型进行匹配,也就是,寻找在所有重载版本中最匹配的
小栗子
class Base {
public long sum(int a, int b) {
System.out.println("base");
return a + b;
}
}
public class Child extends Base {
public long sum(int a, long b) {
System.out.println("child");
return a + b;
}
public static void main(String args[]) {
Child c = new Child();
int a = 2;
int b = 3;
c.sum(a, b);
}
}
class Base {
public long sum(int a, int b) {
System.out.println("base");
return a + b;
}
}
public class Child extends Base {
public long sum(int a, int b) {
System.out.println("child");
return a + b;
}
public static void main(String args[]) {
Child c = new Child();
int a = 2;
int b = 3;
c.sum(a, b);
}
}
2.4父子类型转换
一个父的变量能不能转换成为一个子的变量,取决于这个父类引用的对象类型是不是这个子类或子类的子类
//可以
Base b = new Child();
Child c = (Child)b;
//报错
Base b = new Base();
Child c = (Child)b;
3.类的加载过程
加载一个类时会查看其父类是否已加载,如果没有,则会加载其父类。
一个类的信息主要包括以下部分:其中类初始化代码是先执行父类的,再执行子类的。不过,父类执行时,子类静态变量的值也是有的,是默认值
- 类变量(静态变量)
- public static int s;
- 类初始化代码
- static {
System.out.println("s: "+s);
s = 1;
}
- 类方法(静态方法)
-
- 实例变量
- private int a;
- 实例初始化代码
- {
System.out.println("a: "+a);
a = 1;
}
- 实例方法
- public void step(){
System.out.println("base s: " + s +", a: "+a);
}
- 父类信息引用
-
class Base {
public static int s;
private int a;
static {
System.out.println("基类静态代码块, s: " + s);
s = 1;
}
{
System.out.println("基类实例代码块, a: " + a);
a = 1;
}
public Base() {
System.out.println("基类构造方法, a: " + a);
a = 2;
}
protected void step() {
System.out.println("base s: " + s + ", a: " + a);
}
public void action() {
System.out.println("start");
step();
System.out.println("end");
}
}
public class Child extends Base {
public static int s;
private int a;
static {
System.out.println("子类静态代码块, s: " + s);
s = 10;
}
{
System.out.println("子类实例代码块, a: " + a);
a = 10;
}
public Child() {
System.out.println("子类构造方法, a: " + a);
a = 20;
}
protected void step() {
System.out.println("child s: " + s + ", a: " + a);
}
public static void main(String args[]) {
System.out.println("---- new Child()");
Child c = new Child();
System.out.println("\n---- c.action()");
c.action();
Base b = c;
System.out.println("\n---- b.action()");
b.action();
System.out.println("\n---- b.s: " + b.s);
System.out.println("\n---- c.s: " + c.s);
}
}