Java中this与super

对象的this引用

作用:

         this关键字就是让类中一个方法,访问该类中的另一个方法或属性。

   1、构造器中引用该构造器正在初始化的对象。

   2、在方法中引用调用该方法的对象(哪个对象调用的方法,this就代表那个对象)。this在一个方法中使用this.方法,this作用就是引用该类中另一个方法中的对象(对象通常在main方法中)。this也可以省略不写,效果是一样的。但是对于static修饰的方法中就用类调用方法,不能用this。静态成员(带static的)不能访问非静态成员。


语法:

this.属性

this.方法


重载构造器中调用被包含的构造器初始化代码语法:

this(属性...)


例子:this调用方法。

代码:this用法

class Dog
{
	public void jump()
	{
		System.out.println("jump");
	}

	public void run()
	{
		this.jump();
		System.out.println("Dog");
	}

}

public class DogTest
{
	public static void main(String[] args)
	{
		Dog dog = new Dog();	//生成一个对象
		dog.run();	//对象调用run方法,run方法中的this就知道是dog对象调用的它,所以run方法中的this就表示dog对象。使用this的前提条件就是先有一个对象,然后用对象去调用方法,方法中的this就是该对象了。
	}
}


例子:this在构造器中调用属性

//this在构造器中引用正在初始化的对象。

public class ThisTest
{
	public int foo;

	public ThisTest()
	{
		//如果给下面这句加上注释,那么这就是一个默认构造器。main中System.out.println打印的就是0,语法为:对象.属性
		this.foo = 520;		//this引用的是正在初始化的对象,因为初始化对象是用new 调用构造器来完成的。
	}

	public static void main(String[] args)
	{
		System.out.println(new ThisTest().foo);
	}
}


例子:this在重载的构造器中,调用另一个构造器,来初始化当前构造器中的代码。但是前提是当前构造器初始化的属性包含被调用的构造器的所有属性。

public class ConstructorTest
{
	public String name;
	public int count;
	public double weight;

	public ConstructorTest(String name)
	{
		this.name = name;
	}

	public ConstructorTest(String name, int count)
	{
		this(name);		//调用形式参数列表为name的重载构造器初始化代码。
		this.count = count;
	}

	public ConstructorTest(String name, int count, double weight)
	{
		this(name,count);		//调用形式参数列表为name,count的重载构造器初始化代码。
		this.weight = weight;
	}

	public static void main(String[] args)
	{
		ConstructorTest con = new ConstructorTest("Nina");
		System.out.println(con.name);
		System.out.println(con.count);
		System.out.println(con.weight);
		System.out.println("");

		ConstructorTest con1 = new ConstructorTest("Fengqiang",333);
		System.out.println(con1.name);
		System.out.println(con1.count);
		System.out.println(con1.weight);
		System.out.println("");

		ConstructorTest con2 = new ConstructorTest("okay",333,1.2345);
		System.out.println(con2.name);
		System.out.println(con2.count);
		System.out.println(con2.weight);
	}
}


例子:在静态方法中不能使用this

//从静态方法调用非静态方法出错

public class Test
{
	public void info()
	{
		System.out.println("info");
	}

	public static void main(String[] args)
	{
		info();
	}
}




•在静态方法中访问普通方法的办法就是在静态方法中创建一个新的对象。在上面代码中新创建一个对象Test ok = new Test();  ok.info(); 这样就可以了。




例子:this当做对象被返回

public class ReturnThis
{
	public int age;

	public ReturnThis grow()
	{
		age++;
		return this;	//返回这个对象,this代表就是对象
	}

	public static void main(String[] args)
	{
		ReturnThis r = new ReturnThis();

		r.grow().grow().grow();	//调用这个方法返回了ReturnThis对象,然后又是对象.grow()方法,又返回对象,又调用grow()方法。
		System.out.println(r.age);
	}
}



-----------------------------------------------------------------------------------------------------

super

·super关键字作用类似this,但是super是在有继承(extends)情况下使用的


·super可以调用父类方法与属性。如果子类中的属性或方法与父类中的一样则子类覆盖父类的属性或方法。如果子类中的方法或属性与父类中方法或属性一样,那么调用父类方法或属性就需要使用super关键字。


·子类中有与父类同名的属性,则子类的属性隐藏父类的属性(是隐藏从继承过来的属性,就是说继承过来的属性在子类中只是使用的时候使用的是子类的属性,除非显示的使用super,才调用子类继承过来的属性)


·super可以调用父类中的构造器。语法与this调用重载构造器一样,并且都要放在构造器中第一行。this是调用重载构造器,super是调用父类构造器


·跟this一样,也可以不写super关键字,默认使用。在继承中如果某个方法中访问名为a的属性,但没有显示的指定调用者,则系统查找a属性的顺序为:

(1)在该方法中查找是否有a的局部变量

(2)在当前类中查找

(3)在a属性的直接父类中是否有包含名为a的属性,依次查找a的所有父类,直到java.lang.Object类。

    书上废话真长,就是在当前类能找到就用,找不到就去父类中找,在父类中找不到就编译出错。 


总结:supper:类似this,supper作用在子类中调用从父类继承过来的方法或属性。和this一样,他们不能在带有static的方法中使用。this是在普通类中使用,而super是在继承中使用。



例子:super调用父类方法
//父类
public class Bird
{
	public void fly()
	{
		System.out.println("wo zai fei");
	}
}


//子类
public class Ostrich extends Bird
{
	public void fly()	//可以把子类中的这个方法注释掉,然后再编译执行,就可以看出子类继承父类的方法。此时在子类中用Ostrich对象调用fly方法就会出现“wo hui fei”
	{
		System.out.println("wo hui pao");
		super.fly();	//调用子类继承过来的方法
	}

	public static void main(String[] args)
	{
		Ostrich os = new Ostrich();
		os.fly();	//子类重写了父类中的方法,这里调用的是子类自己的方法。
	}
}

例子:super调用父类属性
public class BaseClass
{
	public int a = 520;
	public static String b = "love";
	}

-------------------------------------

public class SubClass extends BaseClass
{
	public int a = 7;

	public void access()
	{
		System.out.println(a);		//打印当前类的属性a
	}

	public void accessBase()
	{
		System.out.println(super.a);	//调用从父类继承过来的a属性,值是520
		System.out.println(BaseClass.b);		//打印继承过来的b属性,也可以用类名调用类属性,这里用子类名字父类名字都可以。
	}

	public static void main(String[] args)
	{
		SubClass s = new SubClass();
		s.access();
		s.accessBase();
		System.out.println(b);
	}
}

例子:super调用父类构造器
class Base
{
	public double size;
	public String name;

	public Base(double size, String name)
	{
		this.size = size;
		this.name = name;
	}
}

public class Sub extends Base
{
	public String color;

	public Sub(double size, String name, String color)
	{
		super(size,name);		//super()调用父类构造器。
		this.color = color;
	}

	public static void main(String[] args)
	{
		Sub s = new Sub(520.0, "test", "blue");

		System.out.println(s.size + " " + s.name + " " + s.color);
	}
}


·调用父类构造器
    当执行子类构造器时,先上溯到最顶层的父类执行其构造器,然后再一层层的往下(子类)执行,最后才执行本类中的构造器。最层的类是java.lang.Object类。

调用父类构造器执行顺序:
1、执行最顶层父类构造器
2、执行super调用的父类构造器。如果该父类中有多个构造器并且构造器中没有调用构造器,那么其他构造器不会执行,因为super调用的构造器已经执行了,如果没有super调用就只执行一个默认构造器。
3、执行自己的构造器

例子:先执行最顶层父类构造器,在执行super调用父类构造器,最后执行自己的构造器
class A
{
	public A()
	{
		System.out.println("a");
	}
}

class B extends A
{
	public B()
	{
		System.out.println("b1");
	}

	public B(String name, int age)
	{
		System.out.println("b2 " + name + " " + age);
	}
}

public class C extends B
{
	public C()
	{
		super("b2", 2);
		System.out.println("c");
	}

	public static void main(String[] args)
	{
		new C();
	}
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3258098.html