Java学习日记(八)--继承

内容回顾

类:是抽象的对事物的一种描述。描述事物的特征和行为特征【属性】:使用全局变量来描述
行为【功能】:使用方法来描述
构造方法:创建对象并给特征初始化具体值对象:是类的具体的实现
通过类中的构造方法创建出来
每一个对象拥有类所描述的特征,特征值有可能不一样,都可以使用类描述的行 为,
使用时:
1、先使用类来描述一个事物【要么自己描述,要么别人给描述好】
2、必须要创建类的对象
3、使用对象来访问对应的属性和行为 对象名.属性名 对象名.方法名(实际参数)
静态:static 用来修饰类内容的 变量【属性】和方法【行为】
把类当中普通的属性和行为变得特殊化【属性或行为从对象拥有变为类拥有对象 共享】
特征:
1、属于类不属于对象被所有对象共享
2、随着类的加载而加载,随着类的消失而消失
3、访问方式发生变化:由对象调用变为类名调用
4、静态的资源只能使用静态资源
5、可以被静态和非静态的同时使用
变量的定义:固定的格式 数据类型 变量名 = 值; 变量的访问:就近原则
变量的分类:全局变量和局部变量
方法:
普通方法:修饰符 返回值类型 方法名(参数列表){方法体}

静态方法:修饰符 static 返回值类型 方法名(参数列表){方法体} 方法的调用:
普通方法:必须使用对象来调用 对象名.方法名(实际参数) 静态方法:使用类名来调用 类名.方法名
记住:一个方法的方法体中去调用其他的方法或者自己封装:面向对象的封装 对属性和实现细节的包裹
主要体现在对属性的封装,使用private关键字修饰属性提供对应的访问方式:setter和getter方法
工具类:
没有属性只有静态方法的类叫做工具类。自定义的时候遵循工具类的定义原则

课程内容
**

代码块

**
概述:被大阔号单独包裹的代码段叫做代码块
根据位置的不同,命名的不同他的使用时机和功能不一样。分类:
局部代码块构造代码块静态代码块
同步代码块【今天不讲,多线程的时候讲】
局部代码块
概述:定义在方法中的代码块位置:方法的方法体中
作用:给局部变量赋值,或者定义局部变量
代码

import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) { Demo01 demo01 = new Demo01(); demo01.show();
}
public void show() {
int a = 10 ;//局部变量
//局部代码块
{
a = 30 ;
int b = 40;//局部变量System.out.println(a);//30 10 System.out.println(b);//40
}
System.out.println(a);//30 代码块对外面的局部变量的赋值是永久的
//System.out.println(b);输出不了	b变量的生存范围变小了
}
}

总结:
好处:缩小了局部变量的使用范围和生命周期,及时的释放内存空间达到提升运行效率。 注意:
局部代码块可以使用外部的局部变量,但是外部不能使用代码块内部的局部变量
局部代码块内部的局部变量的生命周期比外面的局部变量短,随着代码块的执行完毕就消失了,而外部的局部变量 随着方法的执行完毕而消失
局部代码块定义变量的时候不能和外面的变量重名
执行时机:
方法被调用
构造代码块
概述:定义在成员位置的代码块位置:属性位置【类中方法外】作用:给类的属性赋值
特点:
1、可以给成员属性赋值
2、每次创建对象的时候他都会执行一次
3、构造方法执行前他先执行。执行时机:
创建对象的的时候就执行。

代码

public class Dog { String	name;
int	age ; public Dog() {
super();
System.out.println("空参构造执行了");
}

{
name = "花花"; age = 4;
System.out.println("构造代码块执行");
}
}
package ;

public class Dog_Test {
public static void main(String[] args) {
Dog dog = new Dog();//调用空参构造创建对象System.out.println(dog.name);//null 花花System.out.println(dog.age);//0 4
}
}
结果:
构造代码块执行
空参构造执行了
花花
4

静态代码块

概述:被static修饰的构造代码块更名为静态代码块位置:成员属性位置【类中方法外】
作用:给静态变量赋值格式:
static {代码段}
执行特点:
随着类的加载而加载,只加载一次【只执行一次】
代码示例

public class Person {
String name;
 int age;
static String country;
//构造代码块
{
name = "宝宝"; age = 39;
country = "japan"; System.out.println("构造代码块执行了");
}
//静态代码块 只能给静态变量赋值
static {
//name = "宝宝";
//age = 39; country = "China";
System.out.println("静态代码块执行了");
}
}
package ;

public class Person_Test {
public static void main(String[] args) { System.out.println(Person.country); //China Person person = new Person(); System.out.println(person.name);//宝宝System.out.println(person.age);//39 System.out.println(person.country);//japan Person person2 = new Person();
}
}
结果:
静态代码块执行了
China
构造代码块执行了宝宝
39
japan
构造代码块执行了

案例:
**

验证代码块之间和构造方法的执行顺序【典型的面试题】

**

 public class Animal { int age ;
static String name;
//构造代码块
{
System.out.println("构造代码块执行了"); // 3 6
}

static{

System.out.println("静态代码块执行了"); // 2
}
public Animal(int age) { super();
this.age = age;
System.out.println("有参构造执行了");// 7
}
public Animal() { super();
System.out.println("空参构造执行了");// 4
}
public int getAge() { return age;
}
public void setAge(int age) {
//局部代码块
{
System.out.println("局部代码块执行了"); // 5 8
}
this.age = age;
}
public static String getName() { return name;
}
public static void setName(String name) { Animal.name = name;
}

}
package ;

public class Animal_Test { static {
System.out.println("测试类的静态代码块");	// 1
}
public static void main(String[] args) { Animal animal = new Animal(); animal.setAge(13);
Animal animal2 = new Animal(56); animal2.setAge(23);
}
}
结果
测试类的静态代码块 ‐‐> 1
静态代码块执行了‐‐> 2
构造代码块执行了‐‐> 3
空参构造执行了‐‐> 4
局部代码块执行了‐‐> 5
构造代码块执行了‐‐> 6
有参构造执行了‐‐> 7
局部代码块执行了‐‐> 8
 

注意:
1、优先执行静态代码块【只执行一次】【先加载哪个类就先执行哪个静态代码块;测试类要优先其他类,其他类 根据代码的书写顺序自左往右自上而下的依次执行】
2、创建对象的时候先执行构造代码块 再执行构造方法
3、对象调用方法的时候会执行方法中的内容【局部代码块】
4、再一次创建对象先执行构造代码块 再执行构造方法【就不会去执行静态的代码块】
**

继承

**

概述:子承父业就叫做继承。在java中父类中的资源可以被子类使用,子类中的资源不能被父类使用;父类往往里 面放的是所有子类共性的资源。
java中的类和类【事物于事物之间】有关系吗?本身是没有关系,继承说明类和类之间要发生关系,想办法让类和 类之间产生继承关系。
关键字:extends 可以把两个不相关的类产生父子关系
格式: class 类A【子类】名称 extends 类B【父类名称】 {A的内容}
前提:父类必须存在。好处:
1、代码的复用性提升。
2、利于代码的维护性。
3、是多态的前提。增加代码的扩展性。
无继承
代码

 public class Mouse { String name; int age;
public void eat() { System.out.println("老鼠吃药");
}
}
package com.ujiuye.demo;

public class Cat { String name; int age;
public void eat() { System.out.println("猫吃鱼");
}
}


public class Pig { String name; int age;
public void eat() { System.out.println("猪吃饲料");
}
}

有继承
代码

public class Home_Animal { String name;
int age; String color;
}
package com.ujiuye.demo;
public class Mouse extends Home_Animal { public void eat() {
System.out.println("老鼠吃药");
}
}


public class Cat extends Home_Animal{ public void eat() {
System.out.println("猫吃鱼");
}
}
package com.ujiuye.demo;
public class Pig extends Home_Animal{ public void eat() {
System.out.println("猪吃饲料");
}
}

弊端:
弊端:类和类之间的关系变强,耦合性强耦合性:事物和事物之间的依赖关系的程度

java开发当中:低耦合,高内聚
尽量降低类之间的依赖关系,尽量使用少的对象做多的事情。上午知识点回顾
代码块:
局部代码块:定义在方法中的方法体中作用是给局部变量赋值或者定义局部变量
好处:缩短了局部变量的生命周期一使用范围执行时机:所在方法被调用
构造代码块:定义在成员属性位置的代码块
作用:是成员属性赋值
特点:每次创建对象的时候会优先执行执行时机:创建对象的时候
静态代码块:被是static修饰的构造代码块
作用:给静态变量来赋值或者加载值加载一次的资源特点:随着类的加载而加载【只执行一次】
执行时机:所在类被加载的时候继承:子承父业
实现继承:使用关键字extends 链接两个类实现了继承格式:class 类A extends 类B {类A的内容}
实现了类A 继承了类B
继承关系中的成员变量:
1、子父类中属性名不同名:
父类对象只能使用父类中的变量【属性】,子类对象既能使用子类自己里面的属 性也可以使用父类中的属性
2、子父类中属性名同名:
父类对象只能使用父类自己的,子类对象优先使用自己的同名属性,非要使用父 类的同名属性,使用关键字super来使用父类的同名属性
父类永远使用的是自己的属性,子类自己的和父类他都可以使用

 public class Father { int a = 10 ;
int b = 20 ;

}


public class Son extends Father{
//同名变量int a = 30;
//不同名变量
int c = 40;
public void show() { System.out.println(this.a);//30 System.out.println(super.a);
}
}


public class Son_Test {
public static void main(String[] args) { Father father = new Father();
Son son = new Son(); System.out.println(father.a);//10 System.out.println(father.b);//20
//System.out.println(father.c);访问不了,父类只能使用自己的变量 c 是子类的变量
System.out.println("================"); System.out.println(son.a);//30
System.out.println(son.b);//子类对象访问父类的属性 20
System.out.println(son.c);//40
//System.out.println(son.a); son.show();
}

}
结果:
10
20
================ 30
20
40
30 ‐‐‐>子类的a的值
10 ‐‐‐>父类的a的值

this和super的关系
this:代表当前调用对象
super:代表当前调用对象的父类代码示例

继承关系中构造方法的关系:
概述:父类的构造方法子类不能够继承,但是可以间接的使用。
父类的构造方法就是创建父类对象的,子类使用的时候只需要创建自己的对象就可以 了,不需要创建父类的对象,不用继承父类的构造。【父类的构造子类不继承】
在初始化子类数据之前,必须先完成对父类数据的初始化(因为在初始化子类数据的时候,可能会使用到父类中的 数据,所以必须先把父类数据准备好)。
父类的构造是提供给子类调用的。
this和super的理解图
Java学习日记(八)--继承_第1张图片

涉及的现象:
1、子类在创建对象的时候先初始化父类的相关数据【子类继承父类间接拥有这些数据】
2、在子类的构造方法中没有去调用父类的任何的构造方法,系统会默认的添加一个super()【代表父类的空参构 造】;默认访问父类的空参构造
3、在子类的构造方法中调用了父类的其他的构造方法(),系统就不会添加super();执行你调用的那个父类构 造
练习
定义程序员类和项目经理类
程序员类:属性(姓名、工号、工资)、方法(敲代码)
项目经理类:属性(姓名、工号、工资、奖金)、方法(项目进度控制)

分析:
属性中有 一样的属性,可以把一样的属性提取到一个父类中,程序员和经理去继承父类不用再写这些重复的属性, 独有的自己写在自己的类中
代码示例

public class Employee { String name;//姓名int	id;//工号double salary; public Employee() {
super();

}
public Employee(String name, int id, double salary) { super();
this.name = name; this.id = id; this.salary = salary;
}

}





public class Coder extends Employee{ public void work () {
System.out.println("工作是敲代码");
}

public Coder() { super();

}

public Coder(String name, int id, double salary) { super(name, id, salary);

}

}




public class Manager extends Employee{ double bonus;
public void work() {
System.out.println("工作是控制项目进度");
}
public Manager(double bonus) { super();

this.bonus = bonus;
 }
public Manager() { super();

}
public Manager(String name, int id, double salary) { super(name, id, salary);

}
public Manager(String name, int id, double salary,double bonus) { super(name, id, salary);
this.bonus= bonus;
}

}
package ;

public class Test {
public static void main(String[] args) { Coder coder = new Coder(); System.out.println(coder.id); System.out.println(coder.name); System.out.println(coder.salary);
Manager manager = new Manager("大朗", 001, 20, 0);
System.out.println(manager.id); System.out.println(manager.name); System.out.println(manager.salary); System.out.println(manager.bonus);
}
}

 

继承关系中成员方法的关系:
继承关系中的方法: 方法名不相同:
父类对象只能调用父类中的方法,子类对象可以调用自己的方法也可以调用父类
的方法
方法名称相同:【子类调用的时候优先执行自己里面的方法】
1、子类中的方法可以省略不写
2、子类要更改父类同名方法的方法体方法的重写:
在子父级继承关系中,子类中的方法的返回值类型、方法名、参数列表一模一样,方法体不一样的方法方法的重写 重写的注解:@Override (覆盖 覆写) 编译器编译时检查重写的格式、时机等是否正确。
重写好处:
可以对父类的功能进行修改或增强。

代码

public class Car {
public void show() { System.out.println("这是一辆车");
}
public void print() { System.out.println("这是一辆老牛车");
}
}
package;

public class Bike extends Car{ public void run() {
System.out.println("这个车跑起来很快");
}
//方法和父类中的方法一模一样
//方法的重写
@Override
public void show() { System.out.println("这是一辆自行车");
}
}

重写的注意事项:
1、父类私有的方法,子类不能够重写【不能继承,怎么重写】
2、子类重写的方法要求方法名称、参数列表、返回值类型必须和父类的对应方法一模一样
3、子类重写方法的修饰符可以和父类的不一样【private除外】,但是权限要大于等于父类的权限
4、父类中被final修饰的方法不能够被子类重写
重载和重写的对比:【面试题】

重载:
1、同一个类中
2、方法名相同
3、参数列表不同重写:
1、在两个类中【子父类】
2、方法名相同
3、参数列表相同
4、返回值类型相同

5、修饰符可以不同但是子类的权限大于等于父类的权限
类的继承的特点
继承分类:
单继承:一个类只能继承另一个类
多继承:一个类可以同时继承另外的多个类
多层继承:一个类A继承了类B;类B 有继承类类C java中类的继承:
支持单继承和多层继承,不支持多继承。
final
概述:他是一个关键字,表示最终的含义。用来修饰相关资源的
final修饰的内容:修饰类、属性、方法修饰类:
最终类:不能够被继承
类似于古代皇宫里面的太监。

package ;

public final class Men { String name;
int age; public Men() {
super();

}
public Men(String name, int age) { super();
this.name = name; this.age = age;
}

}
package;

public class Men_Son extends Men{//报错,不让继承

}

修饰变量:变量的值就变成最终的值,不能够再 改变。特点:值不会发生改变了,变相理解为是常量

注意点:
final修饰的变量只能赋值一次,不能第二次赋值。

package ;

public class Demo_final {
public static void main(String[] args) { int a= 10 ;
final int b = 30; final int c ;

a= 20 ;
//b=40;不能够再赋值c=50;
System.out.println(c);
//c=60;
}

}

修饰方法
特点:不能够被子类重写,但是可以被调用【子父类都可以调用】

 package ;

public class Demo_final {
public static void main(String[] args) { int a= 10 ;
final int b = 30; final int c ;

a= 20 ;
//b=40;不能够再赋值c=50;
System.out.println(c);
//c=60;
}
public final void show() { System.out.println("12345上山打老虎");
}
}
package;

public class Demo_Zi extends Demo_final{
/*@Override
public void show() {//报错了 这个方法父类变为final修饰了
System.out.println("100");
}*/
public static void main(String[] args) {

Demo_Zi demo_Zi = new Demo_Zi();

 demo_Zi.show();
Demo_final demo_final = new Demo_final(); demo_final.show();


}
}

你可能感兴趣的:(Java学习)