超牛牪犇Java之代码块&面向对象特征之继承

一.代码块

1.局部代码块

        书写位置:方法中

        作用:限制作用域

2.构造代码块

        书写位置:类中方法外

        代码的执行顺序:

                1️⃣.系统调用的

                2️⃣.只要创建对象就会调用

                3️⃣.构造代码块在构造方法之前被调用

3.静态代码块

        使用关键词 static修饰的代码块

        位置:类中方法外

        调用顺序:

                1️⃣.随着类的加载而加载

                2️⃣.只加载一次

                3️⃣.在构造代码块之前执行

        应用场景:加载驱动(加载数据库驱动--一个类)

4.同步代码块(多线程)--暂时不做介绍

private static void fun1() {
	{	
		int num = 10;
		System.out.println(num);
	}//局部代码块 可以限制变量的作用域
}

小黄鸭调试法:(逻辑调试)

public static void main(String[] args) {	
		Person p1 = new Person();
		p1.name = "Sakura";
		p1.sayHi();
		
		Person p2 = new Person("Naruto",18);
		p2.sayHi();	
	}
class Person{
	String  name;
	int age;
	//无参和有参的构造方法
	public Person() {
		name = "Naruto";
		age = 18;
		System.out.println("我是无参的构造方法");
	}
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
		System.out.println("我是有参的构造方法");
	}
	//介绍自己的方法
	public void sayHi() {
		System.out.println(name + ".." + age + "hahahahaha");
	}
	//吃
	public void eat() {
		System.out.println("吃东西");
	}
	//构造代码块
	{
		System.out.println("我是 构造代码块");
	}
	
	//静态代码块
	static {
		System.out.println(" 我是静态代码块");
	}
}

看一下执行后的结果,思考一下执行的顺序:


example:

public class Demo{
static {
		System.out.println("我是main方法的静态代码块");
	}
	public static void main(String[] args) {
		System.out.println("我是main 函数");
		Test test1 = new Test();
		Test test2 = new Test("Naruto");	
	}
}
class Test{
	String name;
	public Test(){
		System.out.println("我是Test类 无参构造方法");
	}
	public Test(String name){
		System.out.println("我是Test类 有参构造方法");
	}
	{
		System.out.println("我是Test类 构造代码块");
	}
	static {
			System.out.println("我是Test类 静态代码块");
	}
}

打印结果:


二.继承

回顾一下面向对象的特征:

封装 继承 多态

继承:

1.可以进行传递

2.继承的是属性和行为(不是全部)

子类可以继承父类的所有成员变量和成员方法,但不能继承父类的构造方法

3.继承 建立类和类之间的关系

继承的好处:

    1.减少代码量(提高代码的复用性)

    2.提高工作效率

    3.增强了 类与类之间的关系(让类和类之间的关系更加紧密)

继承的弊端:

    (提)高内聚:希望一个类中 方法与方法之间的联系加强

    (降)低耦合:希望类与类之间 减少联系 

    以上只是代表一种思想 并不是绝对的实现

什么时候使用继承?

继承 一定要符合逻辑 把相同的代码抽成一个类 再使用继承

关键字:extends 父类名字

example:猫狗之于动物

把共有的属性如:名字 毛色 抽成一个父类 

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("汪汪汪");
	}

java中只允许单继承(通过接口实现多继承)

java中允许多层继承(继承链) A-->B-->C

当你想只使用功能有方法和属性时 使用哪个类的对象?

一般选择使用继承链 最顶端的类

当你想使用特有方法的时候 使用哪个类的对象?

一般选择使用继承链 最末端的类

如果一个类没有写继承 那么这个类默认继承Object类(基类)

public static void main(String[] args) {
		DemoA a = new DemoA();	Object	
		//当直接打印对象的时候 
		//相当于调用了 Object类中的 toString方法
		System.out.println(a);
	}

打印出来的是:

全类名@16进制的hashcode


三.继承中的构造方法

注意:构造方法是不能被继承的

当创建子类对象的时候,为了保证继承的完整性

(不管在创建子类对象的时候 使用的是无参还是有参构造)

系统会默认帮你调用 父类中的无参构造方法

example:

public class Demo{
	public static void main(String[] args) {
		//Father father = new Father();
		Son son = new Son();
		System.out.println("-----------------");
		Son son1 = new Son("儿子");
	}
}
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{
	String name;
	public Son(){
		//系统帮你在构造方法的 第一行 写了一句代码
		//如果不写 系统会默认帮你加上
		super();//调用了父类的构造方法
		System.out.println("我是儿子的无参构造方法");
	}
	public Son(String name){
		super();//调用父类的构造方法
		this.name = name;
		System.out.println("我是儿子的有参构造方法");
	}
}

系统会在构造方法的 第一行 写一句代码:super();

如果不写 系统会默认帮你加上

打印结果:


四.super和this

super在子类中代表的是父类的对象

this在子类中可以调用子类的属性和方法

(当子类中没有这个属性 和方法的时候 去父类找 找到就用 找不到就报错)

class TestA{
	int num1 = 10;
	int num2 = 20;
	public void fun() {
		System.out.println("我是父类的方法");
	}
}
class TestB extends TestA{
	int num2 = 30;
	public void print() {
		System.out.println(this.num1);
		System.out.println(this.num2);//就近原则
		//直接调用父类的属性 使用super关键词
		System.out.println(super.num2);
		//也可以调父类的方法
		super.fun();
	}
}

可以在子类中构造方法的第一行 调用一下父类的构造方法(有参 无参都可以)

class Car{
	String name;
	//无参构造方法
	public Car() {
		System.out.println("我是Car的无参");
	}
	//有参构造方法
	public Car(String name) {
		this.name = name;
		System.out.println("我是Car的有参");
	}
}
class Audi extends Car{
	//只要你在构造方法的第一行
	//调用一下父类构造方法(无参 有参都行)
	public Audi() {
		super("双钻");
		System.out.println("我是奥迪的无参");
	}
	public Audi(String name) {
		super("三钻");
			this.name = name;
			System.out.println("我是奥迪的有参");
	}
	
}

五.方法重载和方法重写

方法重载:(Overload)(在一个类中进行)

方法重写:(Override)(前提:至少两个类 并且还要有继承关系)

跟父类的方法完全一致

作用:对父类的该方法进行升级

example:

class IOS7{
	public void siri() {
		System.out.print("说英文");
	}
}
class IOS8 extends IOS7{
	String name;
	//注解:表示这个方法是重写父类
	@Override
	public void siri() {
		super.siri();
		System.out.print("说中文");
	}
	//这个方法一般用来 输出本类中的属性
	@Override
	public String toString() {
		//调用的是父类方法
		//打印出来是全类名@16进制的hashcode码
		return "name = "+name;
	}
}

重写父类的方法时 调不调父类的方法要根据你的需求而定

直接打印对象 希望是直接把类的属性输出出来

写一个类都写什么方法?

无参 有参 构造方法

set/get方法

重写toString方法输出属性

private修饰的属性会被子类继承 但是子类无法直接访问

可以间接访问 通过set/get方法来间接访问

六.关键字final

final:

1.修饰方法 方法不能被重写

2.修饰类 类不能被继承

3.修饰变量 变量不能被修改


final修饰引用数据类型不能进行重新指向(地址不能修改)

对象中的属性不会影响修改

一般使用final的时候 会直接定义成静态常量

使用类名直接调用 方便

常量的命名规范 所有字母大写 多单词用下划线分开

ex:

public static final int MAX_VALUE = 10;

堆内存分配的默认值 是无效的默认值

final修饰成员变量的时候 需要赋初始值

赋初始值 有三种方式:

1.声明常量

2.在构造方法中进行赋值

3.在构造代码块中进行赋值

猜你喜欢

转载自blog.csdn.net/enchantedlll/article/details/80272378