一.代码块
A:代码块概述
在Java中,使用{}括起来的代码被称为代码块。
B:代码块分类
根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
C:常见代码块的应用
a:局部代码块
在方法中出现;限定变量生命周期,及早释放,提高内存利用率
b:构造代码块
在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
c:静态代码块
在类中方法外出现,加了static修饰
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。
案例:
package org.westos.demo;
//代码块
public class MyTest {
static {
System.out.println("静态代码块");//3
}
{
System.out.println("构造代码块");//4 6
}
public MyTest(){
System.out.println("构造方法执行");//5 7
}
}
class MyTest2{
static{
System.out.println("MyTest2的静态代码块");//1
}
public static void main(String[] args) {
System.out.println("main方法执行");//2
MyTest myTest=new MyTest();
MyTest myTest2=new MyTest();
}
}
注意事项:
1.代码块:就是被一对大括号{}括起来的内容
2.分类:
1)静态代码块:
A:在类中方法外,用static修饰
B:随着类的加载而加载,在类的加载的时候执行,用于给类进行初始化,并且只执行一次。
C:常常在类加载的时候在静态代码块中写准备工作的代码。
D:只有JVM才能调用
2)构造代码块:
A:在类中方法外
B:创建对象时,构造代码块和构造方法执行 ,并且在构造方法之前执行。
3)局部代码块:
A:在方法中出现
B:限定变量生命周期,及早释放,提高内存利用率
二.继承
1.概述
继承:父辈的财产,子代可以继承。
Java中的继承,父类的成员,子类可以继承使用。
要类和类具有父子关系,可以使用 extends 来实现。
继承可以提高代码的复用性和维护性。
什么时候使用继承
继承其实体现的是一种关系:"is a" .
采用假设法。
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
案例:
创建两个类
package org.westos.demo;
public class Cat {
String name="小猫";
int age=8;
public void catchMouse(){
System.out.println("猫抓老鼠");
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
package org.westos.demo;
public class Dog {
String name="大黑";
int age=10;
public void lookDoor(){
System.out.println("狗看门");
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
在测试类里进行测试:
package org.westos.demo;
public class MyTest3 {
public static void main(String[] args) {
Cat cat=new Cat();
System.out.println(cat.age);//8
System.out.println(cat.name);//小猫
cat.eat();//吃饭
cat.sleep();//睡觉
cat.catchMouse();//猫抓老鼠
System.out.println("=================");
Dog dog=new Dog();
System.out.println(dog.age);//10
System.out.println(dog.name);//大黑
dog.eat();//吃饭
dog.sleep();//睡觉
dog.lookDoor();//狗看门
}
}
如上:可以发现,Cat和Dog类里都有name,age公共变量和eat和sleep公共方法,可以编写一个父类存储,提高代码的复用性;只保留其特有的功能,如Cat类的catchMouse方法和Dog了的lookDoor方法
2.继承的功能
继承:就是把多个事物的共性部分,向上抽取到父类当中,以实现代码的复用性和维护性。只保留其特有的功能
案例:
package org.westos.demo2;
public class Cat extends Animal{
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
package org.westos.demo2;
public class Dog extends Animal{
public void lookDoor(){
System.out.println("狗看门");
}
}
package org.westos.demo2;
public class Animal {
String name;
int age;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
Cat cat=new Cat();
System.out.println(cat.age);//0
System.out.println(cat.name);//null
cat.eat();//吃饭
cat.sleep();//睡觉
cat.catchMouse();//猫抓老鼠
System.out.println("===========");
Dog dog=new Dog();
System.out.println(dog.age);//0
System.out.println(dog.name);//null
dog.eat();//吃饭
dog.sleep();//睡觉
dog.lookDoor();//狗看门
}
}
3.继承的优缺点
继承的好处:提高了代码的复用性,和维护性。
不好之处:让类和类之间产生了父子关系,增加了耦合性。
软件设计的一个原则:高内聚,低耦合
高内聚:一个类独立完成某些功能的能力
耦合:完成一个功能,要去依赖别的类 类跟类之间产生了关系。
继承的语法特点:
1.在Java中:只支持单继承,一个类,只能有一个父类。一个父类,当然可以有多个子类。
2.Java中也支持多层继承 自己--父亲---祖父
```java
package org.westos.demo3;
public class MyTest {
public static void main(String[] args) {
Son1 son1=new Son1();
System.out.println(son1.f);//fffffffffffffffff
System.out.println(son1.g);//ggggggggggggggggg
son1.show();//祖父的show方法
son1.fuShow();//父亲的fuShow方法
}
}
class GrandFather{
String g="ggggggggggggggggg";
public void show(){
System.out.println("祖父的show方法");
}
}
class Father extends GrandFather{
String f="fffffffffffffffff";
public void fuShow(){
System.out.println("父亲的fuShow方法");
}
}
class Son1 extends Father{
}
class Son2 extends Father{
}
4.继承的注意事项
1.父类的私有成员,子类不能继承。
2.构造方法不参与继承。
3.不要为了部分功能而去继承
案例:
package org.westos.demo4;
public class MyTest {
public static void main(String[] args) {
Zi zi=new Zi();
//System.out.println(zi.name);//报错,私有变量子类不能继承
zi.show();//子类的show方法执行了
System.out.println(zi.age);//0
//zi.show1();//报错,私有成员子类不能继承
}
}
class Fu{
public Fu() {
}
private String name="张三";
int age;
public void show(){
System.out.println("父类的show方法执行了");
}
private void show1(){
System.out.println("父类的私有show方法执行了");
}
}
class Zi extends Fu{
public void show(){
System.out.println("子类的show方法执行了");
}
}
5.super和this关键字
1).概述
super:表示的是父类的空间标识,你可以理解为父类的一个引用,或者说是对象。
我们就可以使用super这个关键字,去访问父类的数据
super和this
访问父类的成员变量: super.成员变量名;
访问本类的成员变量: this.成员变量名;
访问父类的成员方法: super.成员方法名();
访问本类的成员方法: this.成员方法名();
访问父类的构造方法: super();
访问本类的构造方法: this();
案例:
package org.westos.demo5;
public class MyTest {
public static void main(String[] args) {
Zi zi=new Zi();
zi.test();
}
}
class Fu{
String name="爸爸";
int age=50;
public void fuShow(){
System.out.println("父类的show方法");
}
}
class Zi extends Fu{
String name="儿子";
int age=18;
public void ziShow(){
System.out.println("子类的show方法");
}
public void test(){
System.out.println(this.name);//儿子
System.out.println(this.age);//18
System.out.println(super.name);//爸爸
System.out.println(super.age);//50
this.fuShow();//父类的show方法
this.ziShow();//子类的show方法
super.fuShow();//父类的show方法
}
}
6.继承中构造方法之间的关系
1).概述
子类中所有的构造方法默认都会访问父类中空参数的构造方法
当我在创建子类对象时,为什么回先去去调用父类的构造方法?
因为有了继承关系后,当我们去初始化子类的 时候,子类要继承父类的一些数据,你子类既然要 继承父类的数据,甚至还要去使用父类的数据
如果说这个时候,父类的数据并没有完成初始化,你子类怎么用
所以,我们在创建子类对象的时候,就会先调用父类的构造方法,来完成父类数据的初始化,然后在初始化自己的数据。
我们在什么时候,去调用的父类构造呢?
在每个类的构造方法中的第一行,有一行默认代码 super() 这行代码就去调用了父类的空参构造。
在Java中有一个顶层 父类 Object 这个类就是老祖宗类,所有的类,都是直接或间接继承自他。
案例一:
package org.westos.demo6;
public class MyTest {
public static void main(String[] args) {
//执行结果:
// 父类构造方法执行了
//子类构造方法执行了
Zi zi=new Zi();
}
}
class Fu extends Object{
int fuNum=100;
public Fu(){
super();
System.out.println("父类构造方法执行了");
}
}
class Zi extends Fu{
int ziNum=200;
public Zi() {
super();
System.out.println("子类构造方法执行了");
}
}
2).问题分析
当我们创建子类对象时,子类的构造方法的第一行,会默认去调用父类的空参构造,但是如果说,父类没有空参构造怎么办?
此时子类的空参构造也会报错,只能用super调用父类的有参构造
1)给父类提供一个空参构造。
2)想办法去调用父类的有参构造。
案例二:
package org.westos.demo7;
public class MyTest {
public static void main(String[] args) {
//Zi zi=new Zi();
Zi zi1=new Zi(3000);
}
}
class Fu{
/* public Fu() {
System.out.println("父类的空参构造执行了");
}*/
public Fu(int num){
System.out.println("父类的有参构造执行了");
}
}
class Zi extends Fu{
public Zi() {
super(100);
System.out.println("子类的空参构造执行了");
}
public Zi(int num){
//super(1000);
this();//先去访问本类的构造方法,然后通过super再去访问父类的有参构造
System.out.println("子类的有参构造执行了");
}
}
执行结果:
父类的有参构造执行了
子类的空参构造执行了
子类的有参构造执行了
3).注意事项
1.父类没有无参构造方法,子类怎么办?
a: 在父类中添加一个无参的构造方法
b:子类通过super去显示调用父类其他的带参的构造方法
c:子类通过this去调用本类的其他构造方法
本类其他构造也必须首先访问父类构造
2.super(…)或者this(….)必须出现在构造方法的第一条语句上
4).经典的面试题
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 Test {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
class Fu {
static {
System.out.println("静态代码块Fu"); //1
}
{
System.out.println("构造代码块Fu"); //3
}
public Fu() {
System.out.println("构造方法Fu"); //4
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi"); //2
}
{
System.out.println("构造代码块Zi"); //5
}
public Zi() {
super();
System.out.println("构造方法Zi"); //6
}
}
class Test{
public static void main(String[] args){
Zi z = new Zi();
}
}
7.方法重写
1).继承中成员方法的关系
当子类和父类出现了一模一样的方法的时候(方法名,参数 返回值一样)就会发生方法覆盖现象,称之为方法重写。
子类方法会覆盖父类方法。
为什么要有方法重写:子类对父类的功能实现,并不是很满意,子类想要改写掉父类的功能,或者说想要扩展父类的功能。那么子类都可以使用方法重写来完成
a:当子类的方法名和父类的方法名不一样的时候
b:当子类的方法名和父类的方法名一样的时候
通过子类调用方法:
a: 先查找子类中有没有该方法,如果有就使用
b:在看父类中有没有该方法,有就使用
c: 如果没有就报错
package org.westos.demo8;
public class MyTest {
public static void main(String[] args) {
Zi zi = new Zi();
zi.fuShow();//父类show方法执行了
zi.ziShow();//子类show方法执行了
zi.eat();//子类的吃饭方法
}
}
class Fu{
public void fuShow(){
System.out.println("父类show方法执行了");
}
public void eat(){
System.out.println("父类的吃饭方法");
}
}
class Zi extends Fu{
public void ziShow(){
System.out.println("子类show方法执行了");
}
@Override
public void eat() {
System.out.println("子类的吃饭方法");
}
}
2).方法重写的概述
A:什么是方法重写
子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
B: Override和Overload的区别?Overload能改变返回值类型吗?
重载是在一个类中,方法名相同,参数列表不同,与返回值无关
重写是指子类对父类的覆盖重写,方法名相同,参数列表相同,只是方法的方法体不同
C:方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
案例一:
package org.westos.demo9;
public class MyTest {
public static void main(String[] args) {
Dog dog=new Dog();
dog.eat();//狗喜欢吃骨头
dog.sleep();//狗喜欢晚上睡觉
System.out.println("======");
Cat cat=new Cat();
cat.eat();//猫吃鱼
cat.sleep();//猫白天睡觉
}
}
class Animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//子类对父类的方法不满意,可以对方法进行覆盖重写,重写后调用以子类方法为准
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫白天睡觉");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗喜欢吃骨头");
}
@Override
public void sleep() {
System.out.println("狗喜欢晚上睡觉");
}
}
案例二:
package org.westos.demo9;
public class Phone {
public void call(){
System.out.println("打电话");
}
public void sendMsg(){
System.out.println("发短信");
}
}
class IPhone extends Phone{
//Override注解可以检测是否为方法的重写
@Override
public void call() {
System.out.println("给刘亦菲打电话");
}
}
class HuaWei extends Phone{
@Override
public void sendMsg() {
System.out.println("给刘亦非发短信");
}
}
package org.westos.demo9;
public class MyTest2 {
public static void main(String[] args) {
IPhone iPhone=new IPhone();
iPhone.call();//给刘亦菲打电话
HuaWei huaWei=new HuaWei();
huaWei.sendMsg();//给刘亦非发短信
}
}
3).重写的注意事项
1.父类私有的方法子类不能重写,因为私有的方法,子类都不能继承何谈重写。
2.子类在重写父类方法时,方法前面的权限修饰符,不能比父类方法的权限修饰符的低。可以比父类的高,也可以一样,最好一样
public>protected>缺省的>private
3.静态方法,不参与重写
案例一:
package org.westos.demo91;
public class MyTest {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show2();
Zi.fuStatic();
Fu.fuStatic();
}
}
class Fu{
public static void fuStatic(){
System.out.println("父类的静态方法");
}
private void show(){
System.out.println("父类私有的静态方法");
}
protected void show2(){
System.out.println("666");
}
}
class Zi extends Fu{
//这里使用Override检测会报错,说明静态方法不能被重写
/* @Override
public static void fuStatic(){
System.out.println("子类的静态方法");
}*/
//同样使用Override检测依旧会报错
/*@Override
private void show(){
System.out.println("子类私有的静态方法");
}*/
//同样报错
// private void show2(){
// System.out.println("666");
// }
}
案例二:
package org.westos.demo92;
public class MyTest {
public static void main(String[] args) {
Student student = new Student();
student.age=88;
student.name="张三";
System.out.println(student.age);//88
System.out.println(student.name);//张三
student.eat();//学生吃辣条
student.sleep();//学生爱睡懒觉
student.study();//学生的工作是学习
System.out.println("==============");
Teacher teacher=new Teacher();
teacher.age=66;
teacher.name="李四";
System.out.println(teacher.age);//66
System.out.println(teacher.name);//李四
teacher.eat();//老师喜欢吃腊肠
teacher.sleep();//老师不喜欢睡觉
teacher.teach();//老师的工作是教书
}
}
class Person {
String name;
int age;
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Student extends Person {
@Override
public void eat() {
System.out.println("学生吃辣条");
}
@Override
public void sleep() {
System.out.println("学生爱睡懒觉");
}
public void study(){
System.out.println("学生的工作是学习");
}
}
class Teacher extends Person {
@Override
public void eat() {
System.out.println("老师喜欢吃腊肠");
}
@Override
public void sleep() {
System.out.println("老师不喜欢睡觉");
}
public void teach(){
System.out.println("老师的工作是教书");
}
}
8.final关键字
1)概述:
A:为什么会有final
由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
B:final概述
final关键字是最终的意思,可以修饰类,变量,成员方法。
分别表示类不可继承,变量不可改变,方法不可重写
2.final修饰特点:
修饰类: 被修饰类不能被继承
修饰方法: 被修饰的方法不能被重写
修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量
注意:
基本类型,是值不能被改变
引用类型,是地址值不能被改变
案例:
package org.westos.demo93;
public class MyTest {
public static void main(String[] args) {
final int num=1000;
//报错,final修饰的num为一个常量,不可改变
// num=2000;
//final 修饰引用类型,指的是 地址值不能再次改变
final Iphone iphone=new Iphone();
//iphone=new Iphone();
}
}
class Phone{
public final void show(){
}
}
class Iphone extends Phone{
//报错,带final修饰的方法不能被重写
/*public final void show(){
}*/
}
final class Animal{
}
//报错,带有final修饰的类不能继承
//class Dog extends Animal{}
三.多态
1.概述
1)多态的概念:
指的是一种事物,在不同时期,所表现出的不同状态。
如:
猫 就是 一只猫,猫是一只动物
Cat cat=new Cat();
Aniaml an=new Cat();
狗就是狗类型,狗是动物类型。
Dog dog= new Dog();
Aniaml an=new Dog();
2)多态的前提:
a:要有继承关系。
b:要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
c:要有父类引用指向子类对象。
父 f = new 子();
Animal an=new Cat();
案例:
package org.westos.demo;
public class MyTest {
public static void main(String[] args) {
//使用多态
Animal animal=new Cat();
animal.eat();//猫吃鱼
animal.sleep();//猫白天睡觉
Animal animal1=new Dog();
animal1.sleep();//狗晚上睡觉
animal1.eat();//狗吃骨头
}
}
class Animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫白天睡觉");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗晚上睡觉");
}
}
2.多态中的成员访问特点
a:成员变量
编译看左边,运行看左边。
采用多态的形式,去访问成员变量,访问的是父类的成员变量
b:构造方法
创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
c:成员方法
编译看左边,运行看右边。
如果子类没有重写父类的方法,就以父类的方法为准,如果子类重写了父类的方法,那么运行时,会以子类重写过后的为准。
d:静态方法
编译看左边,运行看左边。
(静态和类相关,算不上重写,所以,访问还是左边的)
静态方法不参与重写
案例:
package org.westos.demo;
public class MyTest2 {
public static void main(String[] args) {
Animal2 an=new Cat2();
//1.多态访问成员变量
System.out.println( an.age);//333
System.out.println( an.name);//动物
//2.多态访问构造方法
//创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
//3.多态访问成员方法
//如果子类没有重写父类的方法,就以父类的方法为准,如果子类重写了父类的方法,那么运行时,会以子类重写过后的为准。
an.show();//猫的重写show方法
//4.多态访问静态方法
an.staticShow();//父类的静态show方法
}
}
class Animal2{
public Animal2() {
System.out.println("动物的构造方法");
}
String name="动物";
int age=333;
public static void staticShow(){
System.out.println("父类的静态show方法");
}
public void show(){
System.out.println("动物的show方法");
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Cat2 extends Animal2{
String name="猫";
int age=666;
public Cat2() {
System.out.println("猫的构造方法");
}
@Override
public void show() {
System.out.println("猫的重写show方法");
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫白天睡觉");
}
}
class Dog2 extends Animal2 {
String name="狗";
int age=999;
public Dog2() {
System.out.println("狗的构造方法");
}
@Override
public void show() {
System.out.println("狗的重写的show方法");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗晚上睡觉");
}
}
3.多态的好处
a:提高了代码的复用性(继承保证)
b:提高了代码的扩展性(由多态保证)
案例:
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
//在测试类中,一般只需要提供程序的入口就可以了
Dog dog=new Dog();
dog.eat();//狗吃骨头
MyUtils.testEat(dog);
Cat cat=new Cat();
cat.eat();//猫吃鱼
MyUtils.testEat(cat);
Tiger tiger=new Tiger();
tiger.eat();//老虎吃肉
MyUtils.testEat(tiger);
}
}
class Animal{
public void eat(){
System.out.println("动物吃饭");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Tiger extends Animal{
@Override
public void eat() {
System.out.println("老虎吃肉");
}
}
package org.westos.demo2;
//设计一个工具类
public class MyUtils {
//通过方法重载,来设计这个工具类。扩展性不好。因为每增加一种动物。就得在工具类中提供一个重载方法
//私有化构造,表示此类不能直接被实例化,需要通过静态方法直接调用
private MyUtils() {
}
public static void testEat(Animal an){
an.eat();
}
public static void testEat(Cat cat){
cat.eat();
}
public static void testEat(Dog dog) {
dog.eat();
}
public static void testEat(Tiger tiger){
tiger.eat();
}
}
分析:使用多态的话,可以直接传递一个animal进去进行接收 ,不用每一次增加一种动物,都要提供一个重载方法,这样的话,编译看左,运行看右,即编译时的参数为animal,有`eat方法,不报错;运行时传一个具体的参数,cat,执行具体的方法.
4.多态的弊端
不能直接调用子类特有的功能
如何解决:
如果要调用子类特有的方法,我们可以向下转型
向上转型:把子类型,转换成父类型。多态就是向上转型。
案例:
package org.westos.demo3;
public class MyTest {
public static void main(String[] args) {
Animal an = new Cat();
an.eat();
//报错,多态不能直接调用子类特有的功能
//an.show();
//如果要调用子类特有的方法,我们可以向下转型
Animal an2 = new Cat();
Cat cat = (Cat) an2;
cat.show();
Dog dog=(Dog) an2;//会报一个异常,ClassCastException 类型转换异常
//向上转型:把子类型,转换成父类型。多态就是向上转型。
}
}
class Animal {
public void eat() {
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void show() {
System.out.println("猫展腿");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
5.多态的内存图解
6.两道经典面试题
A:看下面程序是否有问题,如果没有,说出结果
class Fu {
public void show() {
System.out.println("fu show");
}
}
class Zi extends Fu {
public void show() {
System.out.println("zi show");
}
public void method() {
System.out.println("zi method");
}
}
class DuoTaiTest3 {
public static void main(String[] args){
Fu f = new Zi();
f.method();
f.show();
}
}
答:父类中没有method方法,编译报错
B:看下面程序是否有问题,如果没有,说出结果
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show();
B b = new C();
b.show();
}
}
答: 爱 你