JavaSEDemo10继承与内部类

简介

  • 本文是2021/04/01整理的笔记
  • 赘述可能有点多,还请各位朋友耐心阅读
  • 本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进

代码的执行顺序:

  • 父类静态代码块 - 子类静态代码块 - 父类初始化代码块- 父类构造方法-子类初始化代码块- 子类构造方法
  • 代码示例
public class Father {
    public Father() {
        System.out.println("父类无参构造方法执行");
    }

    static {
    System.out.println("父类静态代码块执行");
}
    {
        System.out.println("父类初始化代码块执行");
    }
}

public class Son extends Father{
    public Son() {
        System.out.println("子类无参构造方法执行");
    }
    static {
        System.out.println("子类静态代码块执行");
    }
    {
        System.out.println("子类初始化代码块执行");
    }
}

public class TestMain {
    public static void main(String[] args) {
        Son son = new Son();
    }
}

程序运行结果

父类静态代码块执行
子类静态代码块执行
父类初始化代码块执行
父类无参构造方法执行
子类初始化代码块执行
子类无参构造方法执行

易错练习题

第1题

class Super{ 
public static void m1(){ 
System.out.println("m1 in Super"); 
} 
public void m2(){ 
System.out.println("m2 in Super"); 
} 
} 
class Sub extends Super{ 
public static void m1(){ 
System.out.println("m1 in Sub"); 
}
public void m2(){ 
System.out.println("m2 in Sub"); 
} 
} 
public class TestMain{ 
public static void main(String args[]){ 
Super sup = new Sub(); 
sup.m1(); 
sup.m2(); 
Sub sub = (Sub) sup; 
sub.m1(); 
sub.m2(); 
} 
} 

题目1:读程序,写结果
答案:
m1 in Super
m2 in Sub
m1 in Sub
m2 in Sub
解析:statci修饰的方法属于类。
即静态方法看编译期类型,等号左侧

第2题

class MyClass { 
public void printValue(final int value){ 
System.out.println(value); 
} 
public void changeValue(int value){ 
value = value * 2; 
System.out.println(value); 
} 
} 
public class TestMain{ 
public static void main(String args[]){ 
MyClass mc = new MyClass(); 
int value = 5; 
final int fvalue = 10; 
mc.printValue(value); //1 
mc.printValue(fvalue); //2 
mc.changeValue(value); //3 
mc.changeValue(fvalue);//4 
} 
} 

题目2:选择正确答案
A. 编译通过
B. //1 出错
C. //2 出错
D. //3 出错
E. //4 出错
答案: A
解析:最容易误解的地方是mc.changgeValue(fvalue)这一句
Java中向方法中传参的方式是值传递,我们传入的fvalue其实是一个副本,副本是可以改变的,不会影响到fvalue的值。

第3题

abstract class MyAbstractClass{ 
public abstract void m1(); //1 
abstract protected void m2(){} //2 
} 
class MySubClass extends MyAbstractClass{ 
void m1(){} //3 
protected void m2(){} //4 
} 

问:这段代码哪些地方有错误?
A. //1
B. //2
C. //3
D. //4
答:BC
解析:
抽象类中不可以定义private修饰的方法,其他访问权限均可。
第二行,abstract方法没有方法体
第三行,子类重写的方法的权限修饰符要大于等于父类的

第4题

class ClassA{ 
static { 
System.out.println("In ClassA Static"); 
} 
public ClassA(){ 
System.out.println("ClassA()"); 
} 
} 
class ClassB{ 
static { 
System.out.println("In ClassB Static"); 
} 
public ClassB(){ 
System.out.println("ClassB()"); 
} 
} 
class ClassC extends ClassB{ 
static{ 
System.out.println("In ClassC Static"); 
} 
public ClassC(){ 
System.out.println("ClassC()"); 
} 
} 
class MyClass { 
static ClassA ca = new ClassA(); 
ClassC cc = new ClassC(); 
static{ 
System.out.println("In MyClass Static"); 
} 
public MyClass(){ 
System.out.println("MyClass()"); 
} 
} 
public class TestMain{ 
public static void main(String args[]){ 
MyClass mc1 = new MyClass(); 
MyClass mc2 = new MyClass(); 
System.out.println(mc1.cc == mc2.cc); 
System.out.println(mc1.ca == mc2.ca); 
} 
} 

题目4:读程序,写结果
答案:
(1)In ClassA Static
(2)ClassA()
(3)In MyClass Static
(4)In ClassB Static
(5)In ClassC Static
(6)ClassB()
(7)ClassC()
(8)MyClass()
(9)ClassB()
(10)ClassC()
(11)MyClass()
(12)false
(13)true
解析:

  1. 创建mc1对象,先执行Myclass中的静态部分
  2. static ClassA ca = new ClassA();
  3. 执行ClassA中的静态部分,即 (1)In ClassA Static
  4. 再执行ClassA中的无参构造方法,即(2)ClassA()
  5. 执行MyClass中的静态代码块 (3)In MyClass Static
  6. 静态部分执行完毕,开始执行非静态部分
  7. Class cc = new ClassC()
  8. 先执行父类的静态部分,再执行子类的静态部分。即(4)In ClassB Static (5)In ClassC Static
  9. 然后执行子类中的构造方法,子类的构造方法隐含了一句话:super();
  10. 然后执行 父类中的构造方法,即(6) ClassB()
  11. 然后执行子类的构造方法,即(7)ClassC()
  12. Class cc =new ClassC( )执行完毕,(8)输出MyClass( )
  13. 创建mc2对象,此时静态部分不再执行,因为静态部分只执行一次
  14. 所以我们执行Class cc = new ClassC( )
  15. 还是先执行(9)ClassB() 然后执行(10)ClassC()
  16. 然后执行MyClass()
  17. 由于cc是非静态的对象,创建了两次,地址不同false
  18. 由于ca是静态对象,共享,地址相同true

this关键字在内部类中的应用原则

  • this关键字在内部类中,调用的是内部类的变量或方法;如果想调用外部类的变量或方法,需写成外部类.this.变量名或方法名
  • 代码示例:
//外部类
public class OuterClass{
private int age = 10;
//内部类
public class InnerClass{
private int age = 1000;
public void show(){
System.out.println(this.age);
System.out.println(OuterClass.this.age);
}
}
}

class Test{
public static void main(String args[]){ 
OuterClass outerclass = new OuterClass();
OuterClass.InnerClass innerclass = outerclass.new InnerClass();
outerclass.show();
}
}

程序运行结果

1000
10

Lambda表达式

Lambda表达式的用处和组成

  • lambda表达式主要替代了匿名内部类的写法。
  • lambda表达式的基本组成由 参数列表、->、方法体(单句时可不加大括号) 三部
    分组成
  • (参数类型 参数列表) ->
    {
    //匿名内部类的类体
    }

Lambda表达式的适用条件

  1. 返回的实例类型必须是接口
  2. 接口中只有一个需要实现的抽象方法。(只有一个抽象方法的接口也叫函数式接口)

Lambda表达式的使用示例

  1. 接口中定义一个方法methodA,用匿名内部类实现,返回5

使用Lambda表达式前

public class LambdaTest {
    public static void main(String[] args) {
        //创建一个A接口的匿名实现类
        A a = new A(){
        @Override
        public int methodA(){
        return 5;
        }
        }
        System.out.println("a.ma() = " + a.ma());
    }
}
interface A{
    int methodA();
}

程序运行结果

a.ma() = 5 

使用Lambda表达式后

public class LambdaTest {
    public static void main(String[] args) {
        //Lambda表达式
        A a = () -> 5;
        }
        System.out.println("a.ma() = " + a.ma());
    }
}
interface A{
    int methodA();
}

程序运行结果

a.ma() = 5 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香鱼嫩虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值