java中的几种代码块:
局部代码块:
限制变量作用域
书写位置:方法中
构造代码块:
书写位置:类中 方法外
调用时机:创建构造代码块时 系统会自动调用
在创建对象之前调用 并且 每次创建对象都会调用一次
静态代码块(static修饰):
静态代码块 依赖类 随着类的加载而加载
注意:只加载一次(不管你创建多少对象 系统只调用一次)
应用场景:U盘 装载驱动程序
加载驱动(数据库驱动 JDBC)
同步代码块(多线程):
举例:
class Student {
static {
System.out.println("Student 静态代码块");
}
{
System.out.println("Student 构造代码块");
}
public Student() {
System.out.println("Student 构造方法");
}
}
class Demo2_Student {
public static void main(String[] args) {
System.out.println("我是main方法");
Student s1 = new Student();
Student s2 = new Student();
}
static {
System.out.println("Demo2_Student静态代码块");
}
}
需求:根据上述代码 写出打印顺序
分析过程:
1.程序执行过程中 系统先加载Demo2.class
加载Demo2.class时 静态代码块 随着类的加载而加载
打印:“Demo2_Student静态代码块”
2.main函数入栈 代码逐句运行
打印:“我是main方法”
3.创建了s1的对象 加载Student.class
静态代码块 随着类的加载而加载
打印:“Student 静态代码块”
4.有构造代码块 系统会调用
打印:“Student 构造代码块”
6.执行构造方法
打印:“Student 构造方法”
7.创建了s2的对象 加载Student.class
不管创建多少对象 静态代码块 系统只调用一次
不打印:“Student 静态代码块”
8.有构造代码块 系统会调用
打印:“Student 构造代码块”
9.执行构造方法
打印:“Student 构造方法”
最终打印:
Demo2_Student静态代码块
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法
类的继承:
特点:
1.减少代码量(工作量)
2.使类与类之间 产生关联
关键字:extends
弊端:
父类中的弊端属性 也被子类继承
注意:
1.继承时 可以把多个类中 相同的功能或方法 抽取出来
重新构造一个类出来 把这些类 建立继承关系
2.建立继承关系的同时 一定要符合逻辑(切记不要为了继承而继承)
3.java 只允许 单继承(多继承可以使用接口来间接实现)
4.java 中 允许 多层继承
注意:如果是继承的关系 一定符合 什么是什么 子类 是 父类
构造方法 不能被继承
为了保证继承的完整性 在创建子类对象时 如果不调用父类的构造方法 系统会默认去调用 父类无参构造方法
写法:
class 子类 extends 父类 {
}
最顶层父类(最基础类):Object类
如果一个类 没有继承父类 默认继承Object类
思考:
如果我要使用 这些类中 共有方法(属性) 使用那个类?
创建 当前继承中 最顶端类 去使用
如果我要使用 这些类中 特有方法(属性) 创建那个类?
创建 当前继承中 最末端类 去使用
举例:
// 父类
class Father {
String name;
// 无参 有参构造方法
public Father() {
System.out.println("我是爸爸类无参构造方法");
}
public Father(String name) {
this.name = name;
System.out.println("我是爸爸类有参构造方法");
}
public void sayHi() {
System.out.println(name);
}
}
// 子类
class Son extends Father {
// 无参构造
public Son() {
// 如果你没有在子类的构造方法中 调用父类构造方法
// 系统会默认给你的子类方法中 添加一行代码
super(); // 调用父类 无参构造方法
// super 相当于 父类的对象
System.out.println("我是儿子类无参构造方法");
}
// 有参构造
public Son(String name) {
super();// 系统会默认给你的子类方法中 添加一行代码
this.name = name;
System.out.println("我是儿子类有参构造方法");
}
}
// 测试
public static void main(String[] args) {
Son son = new Son();
son.name = "儿子";
son.sayHi();
System.out.println("-------------");
// 有参构造创建对象
Son son2 = new Son("小明");
son2.sayHi();
}
super
super代表是 父类的对象
super调对象与方法的书写
调对象 super.方法
调方法 super.方法();
super();与this();的区别
super(); 调用的父类构造方法
this(); 调用的本类的构造方法
举例:
// 父类
class TestA {
int num1 = 10;
int num2 = 20;
public void sayHi() {
System.out.println("我是父类的sayHi方法");
}
}
// 子类
class TestB extends TestA {
int num1 = 30;
public void fun() {
// 使用this时 会先在类中寻找该属性
// 没找到 就去父类中找
System.out.println(this.num1);
System.out.println(this.num2);
System.out.println(super.num1);
}
}
// 测试
public static void main(String[] args) {
TestB testB = new TestB();
testB.fun();
}
父类与子类的方法重写
定义:
方法声明完全一致的 叫方法重写
注意:
方法的重写 建立在 类与类之前有继承关系(子类重写父类的方法)
Override(重写)和 Overload(重载)的区别
1.重写:需要继承关系
重载:在同一个类中
2.重写:需要方法声明 完全一致
重载:只跟参数 有关
举例:
// 父类
class IOS7 extends Object {
public void call() {
System.out.println("打电话");
}
public void siri() {
System.out.println("说英文");
}
}
// 子类
class IOS8 extends IOS7 {
@Override// 注解 标识这个方法是重写父类方法
public void siri() {
// 调不调父类的方法 要根据实际情况
}
/*
// 方法的重写:对父类方法 进行一个功能上升级
public void siri() {
// 中英文
super.siri();// 调用父类的方法
System.out.println("说中文");
}
*/
// 重写toString()方法
// 利用toString方法 来写 介绍自己的方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "哈哈";
}
}
// 测试
public static void main(String[] args) {
IOS8 ios8 = new IOS8();
ios8.siri();
// 如果直接打印对象 相当于系统会帮你
// 在打印时 调用toString()方法
// 希望能直接打印出来 对象属性值
System.out.println(ios8);
System.out.println(ios8.toString());
}
总结示例
需求:
老师类 学生类
无参 有参构造 set/get方法 成员变量私有化 介绍自己的方法
属性:姓名,年龄
行为:吃饭
老师有特有的方法:讲课
学生有特有的方法:学习
公共类
// 人类
class People {
// 继承中 private修饰的变量 是不能直接访问的
private String name; // 姓名
private int age; // 年龄
// 构造方法
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
// get/set方法
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
// 吃饭
public void eat() {
System.out.println("吃饭");
}
// 介绍自己
public String toString() {
return "姓名:" + name + " 年龄:" + age;
}
}
学生类
class Student extends People {
int num = 0; // 学号
// 构造方法
public Student() {
}
public Student(String name, int age, int num) {
// 直接调用父类的 构造方法 完成初始化
// 为了保证继承的完整性 在子类构造方法中
// 第一行 必须调用父类的构造方法(无参有参都行)
super(name, age);
// 特有属性 直接赋值就行
this.num = num;
}
// 介绍自己
public String toString() {
// 可以在父类的基础上添加自己特有属性打印
return super.toString() + " 学号:" + num;
}
// 学习
public void study() {
System.out.println("学习");
}
}
老师类
class Teacher extends People {
// 构造方法
public Teacher() {
}
public Teacher(String name, int age) {
super(name, age);
}
// 讲课
public void teach() {
System.out.println("讲课");
}
}
main函数中测试
public static void main(String[] args) {
// 创建一个学生
Student student = new Student("王龙", 15, 15);
System.out.println(student);
// 创建一个老师
Teacher teacher = new Teacher("王伟", 26);
System.out.println(teacher);
}