Java基础-08(02)总结帮助文档,代码块,继承

(9)两个面试题:

A:Override和Overload的区别?Overload是否可以改变返回值类型?

B:this和super的区别和各自的作用?

1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?

方法重写:

在子类中,出现和父类中一模一样的方法声明的现象。

方法重载:

同一个类中,出现的方法名相同,参数列表不同的现象。

方法重载能改变返回值类型,因为它和返回值类型无关。

Override:方法重写

Overload:方法重载

2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

this:代表当前类的对象引用

super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)

场景:

成员变量:

this.成员变量

super.成员变量

构造方法:

this(...)

super(...)

成员方法:

this.成员方法

super.成员方法

/*
 问题是:
 我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?
 我还想要输出父类成员范围的num。怎么办呢?
 如果有一个东西和this相似,但是可以直接访问父类的数据就好了。
 恭喜你,这个关键字是存在的:super。
 this和super的区别?
 分别是什么呢?
 this代表本类对应的引用。
 super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
 怎么用呢?
 A:调用成员变量
 this.成员变量 调用本类的成员变量
 super.成员变量 调用父类的成员变量
 B:调用构造方法
 this(...) 调用本类的构造方法
 super(...) 调用父类的构造方法
 C:调用成员方法
 this.成员方法 调用本类的成员方法
 super.成员方法 调用父类的成员方法
*/
class Father {
 public int num = 10;
}
class Son extends Father {
 public int num = 20;
 public void show() {
 int num = 30;
 System.out.println(num);
 System.out.println(this.num);
 System.out.println(super.num);
 }
}
class ExtendsDemo5 {
 public static void main(String[] args) {
 Son s = new Son();
 s.show();
 }
}
/*
 继承中构造方法的关系
 A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
 B:为什么呢?
 因为子类会继承父类中的数据,可能还会使用父类的数据。
 所以,子类初始化之前,一定要先完成父类数据的初始化。
 注意:子类每一个构造方法的第一条语句默认都是:super();
*/
class Father {
 int age;
 public Father() {
 System.out.println("Father的无参构造方法");
 }
 public Father(String name) {
 System.out.println("Father的带参构造方法");
 }
}
class Son extends Father {
 public Son() {
 //super();
 System.out.println("Son的无参构造方法");
 }
 public Son(String name) {
 //super();
 System.out.println("Son的带参构造方法");
 }
} 
class ExtendsDemo6 {
 public static void main(String[] args) {
 //创建对象
 Son s = new Son();
 System.out.println("------------");
 Son s2 = new Son("林青霞");
 }
}
/*
 如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
 报错。
 如何解决呢? 
 A:在父类中加一个无参构造方法
 B:通过使用super关键字去显示的调用父类的带参构造方法
 C:子类通过this去调用本类的其他构造方法
 子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
 注意事项:
 this(...)或者super(...)必须出现在第一条语句上。
 如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
*/
class Father {
 /*
 public Father() {
 System.out.println("Father的无参构造方法");
 }
 */
 public Father(String name) {
 System.out.println("Father的带参构造方法");
 }
}
class Son extends Father {
 public Son() {
 super("随便给");
 System.out.println("Son的无参构造方法");
 //super("随便给");
 }
 public Son(String name) {
 //super("随便给");
 this();
 System.out.println("Son的带参构造方法");
 }
}
class ExtendsDemo7 {
 public static void main(String[] args) {
 Son s = new Son();
 System.out.println("----------------");
 Son ss = new Son("林青霞");
 }
}
/*
 继承中成员方法的关系:
 A:子类中的方法和父类中的方法声明不一样,这个太简单。
 B:子类中的方法和父类中的方法声明一样,这个该怎么玩呢?
 通过子类对象调用方法:
 a:先找子类中,看有没有这个方法,有就使用
 b:再看父类中,有没有这个方法,有就使用
 c:如果没有就报错。
*/
class Father {
 public void show() {
 System.out.println("show Father");
 }
}
class Son extends Father {
 public void method() {
 System.out.println("method Son");
 }
 public void show() {
 System.out.println("show Son");
 }
}
class ExtendsDemo8 {
 public static void main(String[] args) {
 //创建对象
 Son s = new Son();
 s.show();
 s.method();
 //s.fucntion(); //找不到符号
 }
}
/*
 方法重写:子类中出现了和父类中方法声明一模一样的方法。
 方法重载:
 本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
 子类对象调用方法的时候:
 先找子类本身,再找父类。
 方法重写的应用:
 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
 这样,即沿袭了父类的功能,又定义了子类特有的内容。
 案例:
 A:定义一个手机类。
 B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
 按照我们基本的设计,我们把代码给写出来了。
 但是呢?我们又发现新手机应该是手机,所以,它应该继承自手机。
 其实这个时候的设计,并不是最好的。
 因为手机打电话功能,是手机本身就具备的最基本的功能。
 所以,我的新手机是不用在提供这个功能的。
 但是,这个时候,打电话功能就没有了。这个不好。
 最终,还是加上这个功能。由于它继承了手机类,所以,我们就直接使用父类的功能即可。
 那么,如何使用父类的功能呢?通过super关键字调用
*/
class Phone {
 public void call(String name) {
 System.out.println("给"+name+"打电话");
 }
}
class NewPhone extends Phone {
 public void call(String name) {
 //System.out.println("给"+name+"打电话");
 super.call(name);
 System.out.println("可以听天气预报了");
 }
}
class ExtendsDemo9 {
 public static void main(String[] args) {
 NewPhone np = new NewPhone();
 np.call("林青霞");
 }
}
/*
 方法重写的注意事项
 A:父类中私有方法不能被重写
 因为父类私有方法子类根本就无法继承
 B:子类重写父类方法时,访问权限不能更低
 最好就一致
 C:父类静态方法,子类也必须通过静态方法进行重写
 其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
 子类重写父类方法的时候,最好声明一模一样。
*/
class Father {
 //private void show() {}
 /*
 public void show() {
 System.out.println("show Father");
 }
 */
 void show() {
 System.out.println("show Father");
 }
 /*
 public static void method() {
 }
 */
 public void method() {
 }
}
class Son extends Father {
 //private void show() {}
 /*
 public void show() {
 System.out.println("show Son");
 }
 */
 public void show() {
 System.out.println("show Son");
 }
 public static void method() {
 }
 /*
 public void method() {
 }
 */
}
class ExtendsDemo10 {
 public static void main(String[] args) {
 Son s = new Son();
 s.show();
 }
}
/*
 看程序写结果:
 A:成员变量的问题
 int x = 10; //成员变量是基本类型
 Student s = new Student(); //成员变量是引用类型
 B:一个类的初始化过程
 成员变量的初始化
 默认初始化
 显示初始化
 构造方法初始化
 C:子父类的初始化(分层初始化)
 先进行父类初始化,然后进行子类初始化。
 结果:
 YXYZ
 问题:
 虽然子类中构造方法默认有一个super()
 初始化的时候,不是按照那个顺序进行的。
 而是按照分层初始化进行的。
 它仅仅表示要先初始化父类数据,再初始化子类数据。
*/
class X {
 Y b = new Y();
 X() {
 System.out.print("X");
 }
}
class Y {
 Y() {
 System.out.print("Y");
 }
}
public class Z extends X {
 Y y = new Y();
 Z() {
 //super
 System.out.print("Z");
 }
 public static void main(String[] args) {
 new Z(); 
 }
}
 (10)数据初始化的面试题
 A:一个类的初始化过程
 B:子父类的构造执行过程
 C:分层初始化
/*
 看程序写结果:
 A:成员变量 就近原则
 B:this和super的问题
 this访问本类的成员
 super访问父类的成员
 C:子类构造方法执行前默认先执行父类的无参构造方法
 D:一个类的初始化过程
 成员变量进行初始化
 默认初始化
 显示初始化
 构造方法初始化
 结果:
 fu
 zi
 30
 20
 10
*/
class Fu{
 public int num = 10;
 public Fu(){
 System.out.println("fu");
 }
}
class Zi extends Fu{
 public int num = 20;
 public Zi(){
 System.out.println("zi");
 }
 public void show(){
 int num = 30;
 System.out.println(num); //30
 System.out.println(this.num); //20
 System.out.println(super.num); //10
 }
}
class ExtendsTest {
 public static void main(String[] args) {
 Zi z = new Zi();
 z.show();
 }
}
/*
 看程序写结果:
 A:一个类的静态代码块,构造代码块,构造方法的执行流程
 静态代码块 > 构造代码块 > 构造方法
 B:静态的内容是随着类的加载而加载
 静态代码块的内容会优先执行
 C:子类初始化之前先会进行父类的初始化
 结果是:
 静态代码块Fu
 静态代码块Zi
 构造代码块Fu
 构造方法Fu
 构造代码块Zi
 构造方法Zi
*/
class Fu {
 static {
 System.out.println("静态代码块Fu");
 }
 {
 System.out.println("构造代码块Fu");
 }
 public Fu() {
 System.out.println("构造方法Fu");
 }
}
class Zi extends Fu {
 static {
 System.out.println("静态代码块Zi");
 }
 {
 System.out.println("构造代码块Zi");
 }
 public Zi() {
 System.out.println("构造方法Zi");
 }
}
class ExtendsTest2 {
 public static void main(String[] args) {
 Zi z = new Zi();
 }
}
 (11)案例:
 A:学生和老师案例
 继承前
 继承后
/*
 学生案例和老师案例讲解
 学生:
 成员变量;姓名,年龄
 构造方法:无参,带参
 成员方法:getXxx()/setXxx()
 老师:
 成员变量;姓名,年龄
 构造方法:无参,带参
 成员方法:getXxx()/setXxx()
*/
//定义学生类
class Student {
 //姓名
 private String name;
 //年龄
 private int age;
 public Student() {
 }
 public Student(String name,int age) {
 this.name = name;
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
}
//定义老师类
class Teacher {
 //姓名
 private String name;
 //年龄
 private int age;
 public Teacher() {
 }
 public Teacher(String name,int age) {
 this.name = name;
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
}
class ExtendsTest3 {
 public static void main(String[] args) {
 //创建学生对象并测试
 //方式1
 Student s1 = new Student();
 s1.setName("林青霞");
 s1.setAge(27);
 System.out.println(s1.getName()+"---"+s1.getAge());
 //方式2
 Student s2 = new Student("林青霞",27);
 System.out.println(s2.getName()+"---"+s2.getAge());
 //对应的老师测试我不想了,留给你们自己练习。
 }
}
/*
 学生案例和老师案例讲解
 学生:
 成员变量;姓名,年龄
 构造方法:无参,带参
 成员方法:getXxx()/setXxx()
 老师:
 成员变量;姓名,年龄
 构造方法:无参,带参
 成员方法:getXxx()/setXxx()
 看上面两个类的成员,发现了很多相同的东西,所以我们就考虑抽取一个共性的类:
 人:
 成员变量;姓名,年龄
 构造方法:无参,带参
 成员方法:getXxx()/setXxx()
 学生 继承 人
 老师 继承 人
*/
//定义人类
class Person {
 //姓名
 private String name;
 //年龄
 private int age;
 public Person() {
 }
 public Person(String name,int age) { //"林青霞",27
 this.name = name;
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
}
//定义学生类
class Student extends Person {
 public Student() {}
 public Student(String name,int age) { //"林青霞",27
 //this.name = name;
 //this.age = age;
 super(name,age);
 }
}
//定义老师类
class Teacher extends Person {
}
class ExtendsTest4 {
 public static void main(String[] args) {
 //创建学生对象并测试
 //方式1
 Student s1 = new Student();
 s1.setName("林青霞");
 s1.setAge(27);
 System.out.println(s1.getName()+"---"+s1.getAge());
 //方式2
 Student s2 = new Student("林青霞",27);
 System.out.println(s2.getName()+"---"+s2.getAge());
 //补齐老师类中的代码并进行测试。
 }
}
 B:猫狗案例的分析和实现
 /*
 猫狗案例讲解
 先找到具体的事物,然后发现具体的事物有共性,才提取出一个父类。
 猫:
 成员变量:姓名,年龄,颜色
 构造方法:无参,带参
 成员方法:
 getXxx()/setXxx()
 eat()
 palyGame()
 狗:
 成员变量:姓名,年龄,颜色
 构造方法:无参,带参
 成员方法:
 getXxx()/setXxx()
 eat()
 lookDoor()
 共性:
 成员变量:姓名,年龄,颜色
 构造方法:无参,带参
 成员方法:
 getXxx()/setXxx()
 eat()
 把共性定义到一个类中,这个类的名字叫:动物。
 动物类:
 成员变量:姓名,年龄,颜色
 构造方法:无参,带参
 成员方法:
 getXxx()/setXxx()
 eat()
 猫: 
 构造方法:无参,带参
 成员方法:palyGame()
 狗:
 构造方法:无参,带参
 成员方法:lookDoor()
*/
//定义动物类
class Animal {
 //姓名
 private String name;
 //年龄
 private int age;
 //颜色
 private String color;
 public Animal() {}
 public Animal(String name,int age,String color) {
 this.name = name;
 this.age = age;
 this.color = color;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public void eat() {
 System.out.println("不要睡了,该吃饭了");
 }
}
//定义猫类
class Cat extends Animal {
 public Cat() {}
 public Cat(String name,int age,String color) {
 super(name,age,color);
 }
 public void playGame() {
 System.out.println("猫玩英雄联盟");
 }
}
//定义狗类
class Dog extends Animal {
 public Dog() {}
 public Dog(String name,int age,String color) {
 super(name,age,color);
 }
 public void lookDoor() {
 System.out.println("狗看家");
 }
}
//测试类
class ExtendsTest5 {
 public static void main(String[] args) {
 //测试猫
 //方式1
 Cat c1 = new Cat();
 c1.setName("Tom");
 c1.setAge(3);
 c1.setColor("白色");
 System.out.println("猫的名字是:"+c1.getName()+";年龄是:"+c1.getAge()+";颜色是:"+c1.getColor());
 c1.eat();
 c1.playGame();
 System.out.println("---------------");
 //方式2
 Cat c2 = new Cat("杰瑞",5,"土豪金");
 System.out.println("猫的名字是:"+c2.getName()+";年龄是:"+c2.getAge()+";颜色是:"+c2.getColor());
 c2.eat();
 c2.playGame();
 //作业:测试狗
 }
}

本文分享自微信公众号 - Java帮帮(javahelp)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android干货

Python对象相关内置函数

判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple:

16030
来自专栏AILearning

反射的应用与理解

反射就是把Java类中的各种成分映射成相应的java类 <代理模式会用到反射,SSH框架会用到框架> 反射使用用中用到的是:字节码(获取类的字节码的三种方式) ...

22360
来自专栏黑泽君的专栏

HashSet存储元素保证唯一性的代码及图解

15420
来自专栏移动端开发

Swift 内存管理详解

Swift内存管理: Swift 和 OC 用的都是ARC的内存管理机制,它们通过 ARC 可以很好的管理对象的回收,大部分的时候,程序猿无需关心 Swift...

29390
来自专栏DT乱“码”

java父类,子类静态块和构造方法的执行顺序

一个面试笔试题中没什么什么卵用但经常出的题,父类,子类静态块和构造方法的执行顺序 package com.gulf.test; public class Fa...

249100
来自专栏Android干货园

Kotlin初级(2)- - - 空安全.md

如果可空变量为null时,返回null 这种用法大量用于链式操作,能有效避免空指针异常

10230
来自专栏淡定的博客

python入门之面向对象

12910
来自专栏好好学java的技术栈

java基础提升篇:Static关键字

13220
来自专栏java学习

Java每日一练(2017/6/20)

题目要求 本期题目: (单选题) 1、若有定义:byte[]x={11,22,33,﹣66};其中0≤k≤3,则对x数组元素错误的引用是() A x[5-3...

400100
来自专栏和蔼的张星的图像处理专栏

C++面向对象编程一些拾遗

虽然说是拾遗,但是这里有一大部分是我以前没有看过的,简书的markdown不支持生成目录,可能需要手动来一个了。

19820

扫码关注云+社区

领取腾讯云代金券