Day07–面向对象2(继承)
一、代码块
1.概述
- 代码块就是一块被包起来的代码
- 代码块出现的位置不同,名字和作用和用法都不同.
- 出现在成员位置(类里方法外)的代码块,叫构造代码块
- 出现在局部位置(方法里)的代码块,叫局部代码块
2.构造代码块
- 在类里方法外的代码块(成员变量的位置)。
- 通常用于抽取构造方法中的共性代码。
- 每次调用构造方法前都会调用构造代码块
- 优先于构造方法加载
3.局部代码块
- 在方法里面的代码块
- 通常用于控制变量的作用范围,出了括号就失效
- 变量的范围越小越好,成员变量会有线程安全问题
4.测试
package cn.tedu.oop;
//测试 代码块
/*
* 总结:
* 1.构造方法:用来创建对象或者完成对象的初始化,在new时触发
* 2.构造代码块:位置是类里方法外,作用是抽取狗脏方法的共性,在new时触发
* 3.局部代码块:位置是方法类,作用是控制变量的作用范围,当方法被调用时触发
* 4.执行顺序:
* new时:构造代码块>构造方法>局部代码块(调用方法时)
* */
public class Test04_Block {
public static void main(String[] args) {
new Animal();
new Animal("老虎");
new Animal("狮子",8);
new Animal().show();
}
}
class Animal{
//1.构造代码块:在类里方法外,在执行构造方法前执行
{
int num=0;//抽取构造方法的共性
System.out.println("构造代码块");
}
public Animal() {
}
public Animal(String name) {
System.out.println(name);
}
public Animal(String name,int age) {
System.out.println(name+age);
}
public void show() {
//2.局部代码块:位置是在方法里,作用是控制变量的作用范围
{
int x = 10;//x作用范围在局部代码块内
System.out.println("局部代码块"+x);
{
System.out.println("还是局部代码块"+x);
}
}
//System.out.println(x); //报错,超出x的作用范围
}
}
package cn.tedu.oop;
//测试 代码块
//面试题 输出结果是?
public class Test05_Block2 {
public static void main(String[] args) {
new Animal2();
new Animal2(5);
}
}
class Animal2{
public Animal2() {
System.out.println(2);
{
System.out.println(4);
}
}
public Animal2(int a) {
System.out.println(3);
}
{
System.out.println(1);
}
}
二、this关键字
1.概述
- this表示本类对象的一个引用对象
- this多数情况下都是省略不写的,但是有两种情况必须使用this
- 场景1 :当局部变量名 和成员变量名 相同时
- 场景2 :当同一个类里的 构造方法 互相调用时
2.测试
1)当变量名相同时
package cn.tedu.oop;
//测试 this
public class Test06_This {
public static void main(String[] args) {
new Demo().show();
}
}
class Demo{
int age =20;
String name;
public void show() {
int age = 10;
System.out.println(age);//就近原则:当变量名相同时,优先使用局部变量,10
System.out.println(name);//null
Demo demo = new Demo();//创建本类对象
System.out.println(demo.age);
//1.this关键字的作用,就相当于this在低层帮你创建了一个本类对象
//Demo this = new Demo(); this--表示的是本类对象的一个引用
//2.this可以调用本类的成员(成员变量/方法)
System.out.println(this.age);//3.使用this调用成员变量age
}
}
2)构造方法间的调用
- 在构造方法中互相调用时!!!!!
package cn.tedu.opp;
//测试 this关键字
/*
* 总结
* 1.this代表的是 本类对象的一个引用
* 2.this可以省略--不同名时,调用成员变量成员方法,都可以省略this
* 3.以下两种情况this必须不能省略:
* 当局部变量名和成员变量名相同时,通过this调用成员变量
* 当在构造方法中互相调用时,必须通过this调用,且位置必须是第一条语句
* (普通方法里可以放在任意位置)
* */
public class Test01_This {
public static void main(String[] args) {
new Person();
new Person("皮皮霞");
}
}
class Person{
public Person() {
//2.在无参构造中调用含参构造--必须用this()
//this("皮皮霞");
System.out.println("无参构造方法");
}
public Person(String name) {
//1.在含参构造中调用无参构造--必须用this()
this();//3.this关键字出现在构造方法中时,必须是第一条语句
System.out.println(name);
}
}
三、访问控制符
- 用来控制一个类,或者类中的成员的访问范围。
类 | 包 | 子类 | 任意 | |
---|---|---|---|---|
*public* | √ | √ | √ | √ |
*protected* | √ | √ | √ | |
*default* | √ | √ | ||
*private* | √ | |||
四、继承
1.概述
- 是在程序中体现了两个类之间的关系.
- 父类和子类…子类继承父类后,可以使用父类的所有功能,并且还能扩展
- 子类只能继承一个父类
- 好处: 提高了代码的复用性,减少了子类代码的编写
·
2.特点
- 使用extends关键字
- 相当于子类把父类的功能复制了一份
- java只支持单继承
- 继承可以传递(爷爷,儿子,孙子的关系)
- 不能继承父类的私有成员
- 继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展
- 像是is a 的关系
3.测试
package cn.tedu.opp;
//测试 继承
public class Test02_Extends{
public static void main(String[] args) {
//创建子类对象
new Dog().eat();//3.使用了继承来的父类的方法
new Cat().eat();
}
}
class Animal{//1.父类 -- 提取共性 -- 提高了父类代码的复用性
public void eat() {
System.out.println("吃");
}
private void sleep(){//7.不能继承父类的私有成员
System.out.println("睡");
}
}
class Dog extends Animal{//2.子类 -- 继承父类使用功能,使用关键字extends
//4.相当于继承后,子类把父类的功能复制了一份
//5.子类只能继承一个父类--单根继承
}
class Cat extends Dog{//6.继承的传递性(爷爷,儿子,孙子的关系)
//8.继承关系就是is a的关系,是一种强制的依赖关系--强耦合--不提倡
}
五、super关键字
1.特点
- super代表父类对象的一个引用
- super是用在子类中的.用来 调用父类的内容
- 如果出现在构造方法中,super必须是一条语句–类似于this
六、方法的重写override
1.概述
- 前提是发生继承关系.
- 普通的继承关系,可以减少子类代码的编写,提高父类代码的复用性.
- 但是,如果继承过来的方法,想要改?–发生了方法重写的现象.
- 要求:在 子类中的方法声明必须和父类的一样 + 足够的重写的权限
七、继承的使用
1)成员变量的使用
package cn.tedu.opp;
//测试 继承的使用--成员变量
/*
* 总结
* 1.继承关系中,父类的成员变量可以让子类去继承
* 2.子类继承了父类的成员变量后,如何使用?
* 如果子类中没有同名的资源,直接使用(省略super)
* 如果子类中含有和父类同名的资源,必须使用super来调用父类的内容
* */
public class Test03_UseExtends {
public static void main(String[] args) {
new Zi().show();
}
}
class Fu{
String name="jack";
}
class Zi extends Fu{
int age = 10;
String name="rose";
public void show() {
int age = 20;
System.out.println(age);
System.out.println(this.age);
System.out.println(name);//使用了成员变量的rose
//1.super是用在子类中的,用来调用父类的功能
//相当于super帮你创建了一个父类的对象 Fu super =new Fu();
//2.super在多数情况下是可以省略的,但是当成员变量名同名时,通过super调用父类
System.out.println(super.name);//使用父类的成员变量name jack
}
}
2)成员方法的使用
package cn.tedu.opp;
//测试 继承的使用--成员方法
/*
* 总结
* 1.子类可以继承父类的所有方法(除了private的),还能进行扩展,还能修改父类的方法
* 2.方法重写是什么时候发生?--想要改父类原有的功能时
* 重写的要求:子类的方法声明和父亲一样 + 有足够的权限
* 重写后,改的是子类的
* 3.面试题:overload和override的区别?
* overload是重载:同一个类里,方法名相同,但是参数列表不同的现象,好处是灵活
* override是重写:在子类里想要修改父类原来的实现方式,重写的要求:子类的方法声明和父亲一样 + 有足够的权限
* */
public class Test04_UseExtends2 {
public static void main(String[] args) {
new Son().eat();//重写前,使用了父类的方法,重写后使用了子类的方法体
new Son().drink();
// new Son().play();//play()是父类的私有资源,子类无法继承!!
new Son().rush();//使用了子类扩展的方法
}
}
class Father{
public void eat() {
System.out.println("吃");
}
void drink() {//修饰符不写就是默认的default
System.out.println("喝");
}
private void play() {
System.out.println("玩");
}
}
//1.子类可以继承父类的所有方法们(除了private的)
class Son extends Father{
//2.子类可以在继承父类的同时继续扩展
public void rush() {
System.out.println("冲");
}
//3.子类继承方法后,如果想改父类原来的方法?--方法重写
//子类的方法声明/签名必须和父类的一样 + 拥有足够的权限(>=)
public void eat() {
System.out.println("不吃~~");
//super.eat();//验证:父类的方法体也被改了吗?--没有,不许改源码!!!
}
}
3)构造方法的使用
package cn.tedu.opp;
//测试 继承的使用 -- 构造方法
/*
* 1.当创建子类对象时,一定会触发子类的构造方法
* 2.第一行就隐藏着super(),回去执行父类的无参构造(低层已经创建好了父类对象了)
* 构造方法的执行顺序:父类的>子类的
* 3.当父类中只提供了含参构造时,就真的没有无参构造了
* 子类的super()会报错,因为找不到父类的无参构造了,只能调用父类的含参构造
*
* */
public class Test05_UseExtends3 {
public static void main(String[] args) {
new Zi3();
}
}
class Fu3{
// public Fu3() {};
public Fu3(int a){//6.当只提供含参构造时,无参构造就真没了
System.out.println("父类");
}
}
class Zi3 extends Fu3{
public Zi3() {
//1.子类的构造方法里 隐藏着super()
//super();//2.主动调用了父类的无参构造
//3.子类调用父类的构造方法,使用super(),而且位置必须是第一条语句
super(100);//5.只能调用父类的含参构造
System.out.println("子类");
}
}
拓展
1.this和super的区别
- this代表本类对象的引用,super代表父类对象的引用。
- this用于区分局部变量和成员变量
- super用于区分本类变量和父类变量
- this.成员变量 this.成员方法() this(【参数】)代表调用本类内容
- super.成员变量 super.成员方法() super(【参数】),代表调用父类内容
- this和super不可以同时出现在同一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢。。
2.重写与重载的区别(Overload和Override的区别)
- overload是重载:同一个类里,方法名相同,但是参数列表不同的现象,好处是灵活
- override是重写:在子类里想要修改父类原来的实现方式,重写的要求:子类的方法声明和父亲一样 + 有足够的权限