- 这几天刷牛客突然发现对于这些基础东西有点混淆 写写博客来加深印象
一.super关键字回顾
- 关于super关键字作用我就不在这里赘余了
1.父类对子类构造方法的影响
(1).当父类拥有无参构造方法
public class Father {
String name;
String age;
public Father() {
System.out.println("父类的无参构造...");
}
public Father(String name, String age) {
this.name = name;
this.age = age;
}
}
public class Son extends Father {
String id;
String sex;
public Son() {
System.out.println("子类无参构造...");
}
public Son(String id, String sex) {
System.out.println("子类有参构造...");
this.id = id;
this.sex = sex;
}
public static void main(String[] args) {
Son s1 = new Son("123","男");
System.out.println("***********************");
Son s2 = new Son();
}
}
运行结果
父类的无参构造...
子类有参构造...
***********************
父类的无参构造...
子类无参构造...
- 如果父类拥有无参构造方法(无论隐式的还是显式的)且子类中的构造方法又没有明确指定调用父类的哪个构造方法,则子类中没有调用该子类其它构造方法的构造方法使用super()隐式调用父类的无参构造方法
(2).父类没有无参构造方法
public class Father {
String name;
String age;
public Father(String name, String age) {
System.out.println("这是父类有参构造...");
this.name = name;
this.age = age;
}
}
子类会报错
要求子类构造方法必须直接或间接指定调用父类哪个构造方法并且放在有效代码第一行
public class Father {
String name;
String age;
public Father(String name) {
System.out.println("这是父类一个参构造...");
this.name = name;
}
public Father(String name, String age) {
System.out.println("这是父类两个参构造...");
this.name = name;
this.age = age;
}
}
public class Son extends Father {
String id;
String sex;
public Son(String name) {
super(name);//指定
System.out.println("子类一个参构造...");
}
public Son(String id, String sex,String name,String age) {
super(name,age);//指定
System.out.println("子类有参构造...");
this.id = id;
this.sex = sex;
}
public static void main(String[] args) {
Son s1 = new Son("123","男","张三","21");
System.out.println("***********************");
Son s2 = new Son("李四");
}
}
运行效果
这是父类两个参构造...
子类有参构造...
***********************
这是父类一个参构造...
子类一个参构造...
子类必须调用父类的构造方法。
二.内部类回顾
- 使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响
- 使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
- 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独
- 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类
- 创建内部类对象的时刻并不依赖于外围类对象的创建
- 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体
- 内部类提供了更好的封装,除了该外围类,其他类都不能访问
1.内部类分类
(1)成员内部类
public class Outer {
private int age = 99;
String name = "lisi";
public class Inner{
String name = "zhangsan";
final static String id="123";
public void show(){
System.out.println(Outer.this.name);
System.out.println(name);
System.out.println(age);
System.out.println(id);
}
}
public Inner getInnerClass(){
return new Inner();
}
public static void main(String[] args) {
Outer o = new Outer();
Inner i1 = o.new Inner();
i1.show();
System.out.println("**************************");
Inner i2 = o.getInnerClass();
i2.show();
}
}
运行结果
lisi
zhangsan
99
123
**************************
lisi
zhangsan
99
123
- Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,外部类都能访问到
- Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响
- 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象(直接new对象会报错)
内部类 对象名 = 外部类对象.new 内部类( )
-
编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
-
成员内部类中不能存在任何 static 的变量和方法,可以定义常量(因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;非静态内部类的作用域是实例级别;而且常量是在编译器就确定的,放到所谓的常量池了)
-
外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法
-
如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字,如:Outer.this.name
(2).静态内部类: 是 static 修饰的内部类
- 首先static不能修饰外部类
public class Outer {
private int age = 99;
static String name = "lisi";
static String sex="男";
public static class Inner{
String name="zhangsan";
final static String id="123";
public void show(){
System.out.println(new Outer().age);
System.out.println(sex);
System.out.println(Outer.name);
System.out.println(name);
System.out.println(id);
}
}
public static void main(String[] args) {
Inner i = new Inner();
i.show();
}
}
运行结果
99
男
lisi
zhangsan
123
- 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
- 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员
- 如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
- 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类()