1、this的使用
- 1.1、this是一个关键字,是一个引用,保存内存地址指向自身。
- 1.2、this 可以便用在实例方法中,也可以使用在构造方法中。
- 1.3、this出现在实例方法中其实代表的是当前对象。
- 1.4、this不能使用在静态方法中。因为this表示当前对象,而static不需要创建对象就存在。
- 1.5、this.大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略。
- 1.6、this()这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的构造方法,目的是代码复用。
public class Date {
private int month;
private int year;
private int day;
//this使用在构造方法中,
// 构造方法的作用就是给类中的变量赋值
public Date() {
this.year = 1977;
this.month = 9;
this.day = 21;
}
public Date(int year, int month, int day) {
this.month = month;
this.year = year;
this.day = day;
}
//this使用在实例方法中,d1传过来就代表d1,d2穿过来就代表d2
public void detail(){
System.out.println(this.year+"年"+month+"月"+day+"日");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Date d1 = new Date();
d1.detail();//1977年9月21日
Date d2 = new Date(2001, 9, 21);
d2.detail();//2001年9月21日
}
}
2、封装:
就是指private属性不能继承,并且需要设置set和get方法来获取,使其他人得不到内部细节
3、理解继承、多态
两点理解:
(1)向上转型 (父类是上,子类是下)
Person p = new Student();
Person p = new Teacher();
在调用方法时,编译看左边,运行看右边。 在调用属性时,编译和运行都看右边。
(2)向下转型(要注意转时的判断)
public class People {
public String name;
public People(){
// 构造方法的作用是为了给属性赋值,如果方法体为空,则赋默认值,如String类型默认赋null
this.name = "人";
}
public People(String name) {
this.name = name;
}
void run(){
System.out.println("人会跑");
}
// 定义方法的时候,使用父类型作为参数,该方法就可以接收这一父类的一切子类对象,体现出多态的扩展性与便利
//此时在父类People中添加一个PK()方法,其中的形参设置为“People a”要优于“Student a”,
//为什么呢?第一种可以接收该父类的一切子类对象,而第二种只能接收一种,具有局限性
public void PK(People a){
System.out.println(a.name+"参加比赛了!");
}
public void methodA(){
System.out.println("人的方法");
}
public static void main(String[] args) {
People p1 = new Student();
People p2 = new Teacher();
//多态中成员访问特点:
//方法调用:编译看左,运行看右;(run方法)
//在编译的时候,先访问“People a1 = new Student();”的左边“People父类”中的方法,而在运行的时候,会访问右边“Student子类”中的方法;
//变量调用学会分析,分清楚子父类的变量能不能共享,如果子类重新定义了name,
// 那么在子类构造方法中的name就不会是父类.name的值,父类.name的值应该由父类的构造方法确定
//变量调用:编译看左,运行也看左。(多态注重行为多态)
//在编译的时候,会访问“People a1 = new Student();”的左边“People父类”中的变量,并且在运行的时候,仍然访问左边“People父类”中的变量。
p1.run();//学生跑得慢
p2.run();//老师跑的快
System.out.println(p1.name);//人
System.out.println(p2.name);//人
// p1是自动类型转化
// 多态下不能使用子类的独有功能
// p1.sick();
//既然前面说到“多态下不能使用子类的独有功能”,那么该由谁来调用呢?
// 子类独有功能当然还是由子类自己来调用,此时我们就需要引入类型转换的概念:
// 类型转换分为两种,分别是:“自动类型转换、强制类型转换”。
//强制类型转换
People s1 = new Student();
Student s2 = (Student) s1;
s2.sick();
System.out.println(s2.name);//输出子类的name
// 检查类型是否正确
People p = new Student();
if (p instanceof Student){
Student s = (Student) p;
s.sick();
}else if (p instanceof Teacher){
Teacher t = (Teacher) p;
t.run();
}
//
}
}
public class Student extends People {
public String name;//这一行注释后,this.name和super.name的值表示一样,都表示的是父类中的name
public Student(){
super();
this.name = "小学生";
}
public void method(){
String name="初中生";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
@Override
void run() {
System.out.println("学生跑得慢");
}
void sick(){//子类独有的方法
System.out.println("学生生病了");
}
public static void main(String[] args) {
Student student = new Student();
student.method();
}
}
package 多态;
public class Teacher extends People{
public String name ;
public Teacher(){
this.name = "老师";//此时的name和父类中的name没有关系,这个name赋值仅赋值给Teacher中的name
}
@Override
void run() {
System.out.println("老师跑的快");
}
public void methodB(){
System.out.println("老师的方法");
}
}
注意:子类和父类同时出现一样的属性时,要分清楚父类的属性是否会被子类的构造方法所具有的属性传进来。 子类没有父类的属性时,子类可以继承父类的属性,从而父类和子类的属性值相同。
4、super的使用
-
super能出现在实例方法和构造方法中。
-
super的语法是: "super."、 "super()"
-
super不能使用在静态方法中。
-
super.大部分情况下是可以省略的。
-
super.什么时候不能省略呢? 父类和子类中有同名属性,或者说有同样的方法, 想在子类中访问父类的,super.不能省略。
-
super()只能出现在构造方法第一行,通过当前的构造方法先去调用父类中 的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
-
super的使用: super.属性名 —— 访问父类的属性
super.方法名(实参)——访问父类的方法
super (实参)——调用父类的构造方法
理解以下两种参数的传递
public class SuperTest01 {
public static void main(String[] args) {
People p1 = new Student("ll");
People p2 = new Teacher("kk");
System.out.println(p1.name);
System.out.println(p2.name);
}
}
class People{
public String name;
public People() {
}
public People(String name) {
super();//默认存在
this.name = name;
}
}
class Student extends People{
public Student() {
}
//子类Student中没有定义name变量,
//那么其继承父类中的name,也可以构造含参的构造方法
//如果调用子类中的含参构造方法,那么就先调用super(name)即父类的含参构造方法
public Student(String name) {
super(name);
}
}
class Teacher extends People{
public Teacher() {
}
public Teacher(String name) {
super(name);
}
}
和
public class SuperTest02 {
public static void main(String[] args) {
People1 p1 = new Student1("ll");
People1 p2 = new Teacher1("kk");
System.out.println(p1.name);
System.out.println(p2.name);
}
}
class People1{
public String name;
public People1() {
this.name = "人";
}
public People1(String name) {
super();//默认存在
this.name = name;
}
}
class Student1 extends People1{
public String name;
public Student1() {
}
//如果调用子类中的含参构造方法,那么就先调用super(name)即父类的含参构造方法
public Student1(String name) {
super(name);//默认的是super(),不含参,含参这一部分将people中的name也定义为kk和ll
this.name = name;
}
}
class Teacher1 extends People1{
public String name;
public Teacher1() {
}
public Teacher1(String name) {
//这里省略的是super()即跳转到不含参的父类构造方法,
// 所以对象p2的name值没有传过来,故Teacher1.name的值为kk,而People1.name的值为“人“
this.name = name;
}