一、代码块
1.局部代码块
书写位置: 在方法中书写
局部代码块的作用: 限制变量的作用域
2.构造代码块
书写位置: 在类中 方法外书写
class ConsCode{
// 成员变量
int a;
int b;
// 空参构造
public ConsCode() {
//System.out.println("HelloWorld!");
System.out.println("11我在构造代码块执行结束之后执行...");
}
// 给变量a赋值的构造
public ConsCode(int a) {
this.a = a;
System.out.println("22我在构造代码块执行结束之后执行...");
//System.out.println("HelloWorld!");
}
// 给变量ab同时赋值的构造
public ConsCode(int a , int b) {
this.a = a;
this.b = b;
//System.out.println("HelloWorld!");
System.out.println("33我在构造代码块执行结束之后执行...");
}
// 构造代码块
{
System.out.println("构造代码块!。。。。。。。。。。。。。。。");
}
}
public class ConstructorCodeDemo {
public static void main(String[] args) {
// 分别使用3个构造方法创建对象,并运行程序,显示执行3遍HelloWorld!
ConsCode c1 = new ConsCode();
ConsCode c2 = new ConsCode(10);
ConsCode c3 = new ConsCode(10,20);
}
}
构造代码块的执行顺序:
1. 系统调用构造代码块
2.只要创建对象 就会调用 创建对象时执行一次
3.构造代码块 在构造方法之前被调用 构造方法隐式三步的最后一步
构造代码块的作用: 有方法需要被每个对象都调用时,将该方法在构造代码块中调用 (不常用)
3.静态代码块
使用关键字 static 修饰的代码块
书写位置: 在类中 方法外书写
调用顺序:
1.随着类的加载而加载(在创建对象之前)
2.只加载一次
3.在构造代码块之前执行
应用场景: 加载驱动---只需加载一次
4.同步代码块(多线程部分)
class Person{
String name;
int age;
public Person(){
System.outprintln("无参构造方法");
}
public Person(){
this.name = name;
this.age = age;
System.out.println("有参构造方法");
}
public void sayHi() {
System.out.println(name + "***" + age);
}
// 构造代码块
{
this.eat();
System.outprintln("构造代码块");
}
// 静态代码块
{
System.outprintln("静态代码块");
}
}
代码块的打印顺序:
1.main方法的静态代码块
2.构造对象引用的类中的静态代码块
3.类中的构造代码块
4.类中的构造方法
public class Demo02 {
static {
System.out.println("我是main方法的静态代码块");
}
public static void main(String[] args) {
System.out.println("我是main函数");
Test test1 = new Test();
Test test2 = new Test("肖锋");
}
}
class Test {
String name;
public Test() {
System.out.println("我是Test类 无参构造方法");
}
public Test(String name) {
this.name = name;
System.out.println("我是Test类 有参构造方法");
}
{
System.out.println("我是Test类 构造代码块");
}
static {
System.out.println("我是Test类 静态代码块");
}
}
// 打印结果
我是main方法的静态代码块
我是main函数
我是Test类 静态代码块
我是Test类 构造代码块
我是Test类 无参构造方法
我是Test类 构造代码块
我是Test类 有参构造方法
我是main方法的静态代码块
我是main函数
我是Test类 静态代码块
我是Test类 构造代码块
我是Test类 无参构造方法
我是Test类 构造代码块
我是Test类 有参构造方法
二、继承
面向对象的特征: 封装 继承 多态
继承 (关键词 extends) :
1.可以进行传递
2.继承的是 属性 和 行为/方法(不是全部的)
3.继承 建立 类与类之间的关系
继承的优点:
1. 减少代码量 (复用性强)
2. 提高工作效率
3. 增强了类与类之间的关系
继承的弊端: 违反了面向对象的高内聚低耦合原则中的低耦合
使用继承 一定要符合逻辑
(子类) 是 (父类)
苹果 是 水果
public class Demo03 {
public static void main(String[] args) {
// 创建一个猫
Cat cat = new Cat();
cat.name = "Tom";
cat.color = "蓝白色";
cat.sayHi();
cat.speak();
// 创建一个狗
Dog dog = new Dog();
dog.name = "大白";
dog.color = "白色";
dog.sayHi();
dog.speak();
}
}
class Animal {
String name;
String color;
public void sayHi() {
System.out.println(name + "..." + color);
}
}
class Cat extends Animal {
public void speak() {
System.out.println("喵喵喵");
}
}
class Dog extends Animal {
public void speak() {
System.out.println("汪汪汪");
}
}
注意:
1.Java中只允许单继承(但可以通过接口来实现多继承)
2.Java中还允许多层继承(继承链)
3.如果一个类并没有写继承 这个类 默认继承的 Object类(基类)
若 使用共有方法和属性 一般选择继承链最顶端类的对象
若 使用特有方法和属性 一般选择继承链最末端类的对象
public static void main(String[] args) {
DemoA a = new DemoA();
// 当直接打印这个对象的时候
// 相当于直接调用的 Object类中 toString方法
System.out.println(a);
}
继承中的构造方法
注意: 构造方法是不被继承的
构造方法---初始化成员变量
子类在书写构造方法的时候 如果没有在第一行书写 super();
系统会自动默认在构造方法的第一行加上 super();
通过 super(); 调用父类的构造方法
所以说 构造方法没有被继承
super 和 this
super 在子类中代表的是父类的对象
(使用 super.变量名 可以直接调用父类的属性; super.方法名() 也可以直接调用父类的方法)
this 在子类中 可以调用子类的属性和方法 可以调用自身(递归)
(当子类中不存在这个属性或者方法时 就会去父类中查找 找不到会报错)
注意:
在的构造方法的第一行调用一下父类的构造方法(无参 有参都可以)!
这时 无论父类中是 有参构造方法还是无参构造方法 都不会出错!
public Audi() {
super("双钻"); // 或者 super();
System.out.println("我是奥迪的 无参");
}
public Audi(String name) {
super("双钻"); // 或者 super();
this.name = name;
System.out.println("我是奥迪的 有参");
}
三、重写
方法的重载(Overload) (在一个类中进行)
方法的重写(Override) (前提:至少两个类 并且有继承关系)
方法的重写 作用: 相当于 对父类的该方法 进行升级
重写: 样式跟父类的方法 完全一致
书写一个类 都写什么方法?
有参 无参构造方法 set/get方法
重写toString方法 输出属性
重写父类的方法时 需不需要调用父类的方法 根据需求而定
class IOS8 extends IOS7 {
// 注解: 标识这个方法是重写父类的
@Override
public void siri() {
super.siri();
System.out.println("说中文");
}
// 这个方法 一般用来 输出本类中的属性
@Override
public String toString() {
// 调用的是父类的方法
// 并且打印出来默认 是 全类名@16进制hashcode码
return "我就想看看属性";
}
}
关键字 final
1. 修饰方法---方法不能被重谢
2. 修饰类---类不能被继承
3. 修饰变量---变量值不能修改
(final 修饰成员变量的时候 前提:成员变量需要赋值初始值)
final修饰引用数据类型时:
该引用数据类型不能进行重新指向(指向的地址不能改)
但是 不影响修改对象中的属性
public static void main(String[] args) {
final int num = 10;
num = 20; // 不可修改 会报错
}