3.修饰代码块
static{ //静态代码块 }
public class StaticDemo { //属于class. jvm只要加载class文件 必然会优先执行或者初始化静态的成员。 static { System.out.println("静态代码块。。。。。。。。。。。。。1"); } //演示代码块 //对于普通代码块而言 new一次 就会被执行一次 { System.out.println("普通代码块............2_1"); } { System.out.println("普通代码块............2_2"); } public StaticDemo() { System.out.println("无参构造................3"); } }
静态代码块。。。。。。。。。。。。。1 普通代码块............2_1 普通代码块............2_2 无参构造................3
public class UserInfo { //声明一个静态用户对象 public static UserInfo instance;//null static { //一般初始化静态的成员变量的数据 //只执行1次 instance = new UserInfo(); } private UserInfo() { } }
class UserInfoTest { public static void main(String[] args) { /*UserInfo user1 = new UserInfo(); UserInfo user2 = new UserInfo(); System.out.println(user1==user2);*///false*/ //保证用户这个类 在这个程序里面有且只有这一个对象 (new 一次) //1. 不能随意访问构造方法 UserInfo user1 = UserInfo.instance; UserInfo user2 = UserInfo.instance; System.out.println(user1 == user2); } }
3. 继承 extends
继承是设么? 为什么要继承? 好处? 子承父业 代码级别? 提高程序或者代码的复用性。 多次使用代码 减少代码冗余。 站在程序的设计角度:
3.1 需求: 马戏团很多小动物表演
Monkey Lion Tiger .....
public class Lion { private String name; private int age; private String leader; public void show(){ System.out.println(name+"正在钻火圈。。。。。。。。。"); } 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 getLeader() { return leader; } public void setLeader(String leader) { this.leader = leader; } }
public class Monkey { //属性 private String name; private int age; //方法 public void show() { System.out.println(name + "正在表演骑车......"); } 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; } }
//测试小动物的表演: 成功地输出表演的内容 //吉吉国王正在表演骑车...... //辛巴正在钻火圈。。。。。。。。。
3.2 继承语法
生活中: 一个父亲有多个孩子。 一个孩子肯定是有一个1个父亲。 代码: public class 父类 extends Object{ //成员变量 成员方法 } public class 子类1/派生类 extends 父类/基类{ } public class 子类2/派生类 extends 父类/基类{ } 一个父类可以有多个子类。 每个子类肯定只有1个父类。 对于子类: 子类自动获得父类里面成员变量和成员方法。(排除private) 子类也可以拥有自己独有的一些属性/方法。 子类比父类更加具体。 子类>=父类----> 只要是父类出现的地方 子类都可以代替。
3.3 使用继承解决小动物问题
@Setter @Getter public class Animal { private int age; private String name; public void show() { System.out.println(name + "正在表演......"); } public Animal(int age, String name) { this.age = age; this.name = name; } public Animal() { } }
@Setter @Getter public class Lion extends Animal{ //独有属性 private String leader; }
public class Monkey extends Animal { }
吉吉国王正在表演...... 辛巴正在表演...... //发现输出的结果都是执行的父类功能。 与需求不符、
3.4 方法重写
-
子类重写的方法名/形参必须与父类的方法保持一致
-
子类重写的返回值类型<=父类方法的返回值类型
-
子类重写的修饰符>=父类的方法的访问权限修饰符
@Setter @Getter public class Lion extends Animal { //独有属性 private String leader; //实现方法重写(覆盖) @Override// 标记注解 标记方法重写的父类的方法 public void show() { System.out.println(this.getName()+"正在钻火圈..................."); } }
public class Monkey extends Animal { @Override public void show() { System.out.println(this.getName()+"正在表演骑自行车.................."); } }
3.5 初始化子类对象流程
@Setter @Getter public class Child extends ParentClass { private int num1; private int num2; static { System.out.println("Child。。。。。。static"); } public Child() { super(); System.out.println("Child无参构造。。。。。。。。。。"); } }
@Setter @Getter class ParentClass { private int id; private String name; static { System.out.println("ParentClass。。。。。。static"); } public ParentClass() { this.id = 0; this.name = null; System.out.println("ParentClass的无参构造......"); } }
class Test { public static void main(String[] args) { Child childObj1 = new Child(); System.out.println(); Child childObj2 = new Child(); //会输出什么内容? 会支持子类无参以及父类无参 //构造方法: 初始化成员变量数据 //创建子类对象 优先执行父类的构造方法 //原因: 在子类的构造里面 默认调用了父类的构造 super(); //执行流程: //1. jvm加载各种class //2. 在子类的无参构造中 默认调用了父类的构造 // 继承关系下: 子类对象----> 父类的是服务于子类。 //假如父类与子类里面都有静态代码块? //1. jvm先加载class 优先执行静态代码块 // 1.1 父类里面的静态 // 1.2 子类里面静态 // 1.3 执行父类构造 // 1.4 子类构造 } }
3.6 使用有参创建子类对象
@Setter @Getter public class Person { private int id; private String name; private int age; public Person(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public Person() { } } //父类里面没有无参构造的话 子类一般都会出现问题(找不到父类的无参构造) //子类里面 默认存在无参构造的 默认调用父类的无参构造 class Man extends Person { public Man() { } public Man(int id, String name, int age) { this.setId(id); this.setName(name); this.setAge(age); } }
class Test { public static void main(String[] args) { //创建子类对象 Man zhangSanObj = new Man(); zhangSanObj.setId(1); zhangSanObj.setName("张三"); zhangSanObj.setAge(20); System.out.println(zhangSanObj.getId()); System.out.println(zhangSanObj.getName()); System.out.println(zhangSanObj.getAge()); System.out.println("------------------------------------"); //想使用子类有参构造初始化成员变量数据 Man liSiObj = new Man(2, "lisi", 30); System.out.println(liSiObj.getId()); System.out.println(liSiObj.getName()); System.out.println(liSiObj.getAge()); } }
3.7 super
1.1 在子类里面 访问父类的成员变量和方法
class Child extends Father { private int num1 = 2000; //不要重名就ok了 public void a() { /* System.out.println(num);//2000 System.out.println(this.num);//2000 //super 可以访问父类的成员 System.out.println(super.num);//1000*/ this.b(); super.b(); } //子类会重写 @Override public void b() { System.out.println("子类重写过后逻辑............"); } }
//在子类构造中 默认调用的无参构造 class Man extends Person { public Man(int id, String name, int age) { super(id, name, age); } public Man() { super(); } } //在继承关系下: 父类提供了有参和无参 子类也会提供有参和无参 子类有参调用父类有参 子类无参调用父类无参