1.this关键字
① 当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量。(this是当前对象自己)
② 把自己当作参数传递时,也可以用this.(this作当前参数进行传递)
class A {
public A() {
new B(this).print();// 调用B的方法
}
public void print() {
System.out.println("HelloAA from A!");
}
}
class B {
A a;
public B(A a) {
this.a = a;
}
public void print() {
a.print();//调用A的方法
System.out.println("HelloAB from B!");
}
}
public class HelloA {
public static void main(String[] args) {
A aaa = new A();
aaa.print();
B bbb = new B(aaa);
bbb.print();
}}
结果为:
HelloAA from A!
HelloAB from B!
HelloAA from A!
HelloAA from A!
HelloAB from B!
在这个例子中,对象A的构造函数中,用new B(this)把对象A自己作为参数传递给了对象B的构造函数。
③ 有时候,我们会用到一些内部类和匿名类,如事件处理。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。如:
public class HelloB {
int i = 1;
public HelloB() {
Thread thread = new Thread() {
public void run() {
for (int j=0;j<20;j++) {
HelloB.this.run();//调用外部类的方法
try {
sleep(1000);
} catch (InterruptedException ie) {
}
}
}
}; // 注意这里有分号
thread.start();
}
public void run() {
System.out.println("i = " + i);
i++;
}
public static void main(String[] args) throws Exception {
new HelloB();
}
}
④ 在构造函数中,通过this可以调用同一类中别的构造函数。
值得注意的是:
1:在构造调用另一个构造函数,调用动作必须置于最起始的位置。
2:不能在构造函数以外的任何函数内调用构造函数。
3:在一个构造函数内只能调用一个构造函数
⑤ this同时传递多个参数。
public class TestClass {
int x;
int y;
static void showtest(TestClass tc) {//实例化对象
System.out.println(tc.x + " " + tc.y);
}
void seeit() {
showtest(this);
}
public static void main(String[] args) {
TestClass p = new TestClass();
p.x = 9;
p.y = 10;
p.seeit();
}
}
结果为:9 10
代码中的showtest(this),这里的this就是把当前实例化的p传给了showtest()方法,从而就运行了。
2.面向对象特性之一:继承
简单的说,规则是这样的:
在子类构造方法中,不管是程序员手动调用父类构造方法还是编译器自动调用,
子类构造方法必须要调用父类的某个构造方法;
被子类调用的父类构造方法在父类中必须是存在的;
参考链接:https://www.cnblogs.com/chenpi/p/5486096.html
3.方法的重写
定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
要求:
重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值类型。
重写方法不能使用比被重写方法更严格的访问权限。
重写和被重写的方法须同时为static的,或同时为非static的
子类方法抛出的异常不能大于父类被重写方法的异常
总结:
方法的重写(override)要遵循两同两小一大的原则:(子类方法相对于父类方法)
1)两同
1.1)方法名相同
1.2)方法参数列表相同
2)两小
2.1)返回类型若为引用类型必须小于或等于父类的,若为基本类型或者void则必须相同
2.2)抛出的异常必须小于等于父类的
3)一大
子类方法的访问权限要大于等于父类的
4.super关键字的几个用法
① 使用访问除了私有以外的属性
② 使用访问除了私有以外的方法
③ 使用访问父类的构造方法
5.关于子类创建构造方法
① 子类中所有的构造器默认都会访问父类中空参数的构造器
② 当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者 父类中相应的构造器,且必须放在构造器的第一行
④ 如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错
6.为什么java的构造方法中this()或者super()要放在第一行?
java的构造方法中如果自己显性的调用super()的时候一定要放在第一行,如不是的话就会报错。
为什么一定要在第一行?
super()在第一行的原因就是: 子类有可能访问了父类对象, 比如在构造函数中使用父类对象的成员函数和变量, 在成员初始化使用了父类, 在代码块中使用了父类等, 所以为保证在子类可以访问父类对象之前要完成对父类对象的初始化。
this()在第一行的原因就是: 为保证父类对象初始化的唯一性. 我们假设一种情况, 类B是类A的子类, 如果this()可以在构造函数的任意行使用, 那么会出现什么情况呢? 首先程序运行到构造函数B()的第一行, 发现没有调用this()和super(), 就自动在第一行补齐了super() , 完成了对父类对象的初始化, 然后返回子类的构造函数继续执行, 当运行到构造函数B()的"this(2) ;"时, 调用B类对象的B(int) 构造函数, 在B(int)中, 还会对父类对象再次初始化! 这就造成了对资源的浪费, 当然也有可能造成某些意想不到的结果, 不管怎样, 总之是不合理的, 所以this() 不能出现在除第一行以外的其他行!
7.this和super的区别