入门JAVA第六天 面向对象

本文详细介绍了Java中的面向对象编程概念,包括类的创建、对象的实例化、构造方法的作用,以及继承和多态的原理。通过实例展示了如何定义类、创建对象、使用构造方法以及如何进行方法重写。此外,还探讨了封装、继承和多态在软件设计中的重要性。
摘要由CSDN通过智能技术生成

一、JAVA第一阶段学习内容与方法

1.1 学习内容

        专业高级阶段的5个核心内容:

第一个阶段是Java核心语言。

        分三个小阶段:

                Java语言基础

                Java面向对象

                Java语言高级

1.2 学习目标 

分成二个层次

                第一个层次:必须掌握:OOP 能写。基本语法。能看懂。

                第二个层次:提高理解:OOA&D 会写。必须在理解的基础。

OOP:Object Oriented Programming (面向对象编程) 编码阶段codding

OOA: Object-Oriented Analysis(面向对象分析) 是确定需求或者业务的角度,按照面向对象的思想来分析业务。 

OOD: Object-Oriented Design (面向对象设计) 面向对象设计是OO方法中⼀个中间过渡环节。主要作用是对OOA结果作进⼀步的规范化整理,以便能够被oop直接接收

1.3 学习方法

1 基本语法,必须背。必须 掌握。

2 软件设计方向,OOAD。理解。想。为什么?

        脑子要动起来。想为什么。

二、对比面向过程与面向对象

        面向过程和面向对象都是编写应用程序的一种方法。

2.1 区别

面向过程是一种以过程(方法)为最小颗粒度的编程语言。

        一个方法一旦声明完成,这个方法的功能就不能改变了。

面向对象是一种以过程中使用的对象为最小颗粒度的编程语言。

        一个方法声明完成,会根据使用的对象的不同,而改变这个方法的功能。

 2.2 案例:盖房子

不管面向过程,还是面向对象,实现功能都需要有相应的业务逻辑。

        盖房子:打地基 -> 砌墙 -> 封顶 这是一个固定的步骤

(1)  面向过程语言

打四方地基( ){ },打圆地基( ){ }

砌四方墙( ){ },砌圆墙( ){ }

封平顶( ){ }

盖房子A( ){

        打四方地基();

        砌四方墙();

        封平顶();

}

盖房子B( ){

        打圆地基();

        砌圆墙();

        封平顶();

}

问:盖房子A这个方法,每调用一次,输出的结果一定是一个四方的房子。

        面向过程语言,一个方法一旦编写完成,功能就固定了。想要一个不同功能的方法就只能新编写一个。

 (2) 面向对象语言

面向对象语言,最小的颗粒度是过程实现过程中使用到的对象

面向对象语言中第一件事是找对象

先找到打地基,砌墙和封顶的对象

封装

class 打地基类{ void 打地基(); }

继承

class 打四方地基类 extends 打地基类{ void 打地基( ) { “打四方地基” } }

        打四方地基类 打四方地基对象 = new 打四方地基类(); //获得一个打四方地基的对象(人)

class 打圆地基类 extends 打地基类{ void 打地基( ) { “打圆地基” } }

        打圆地基类 打圆地基对象 = new 打圆地基类(); //获得一个打圆地基的对象。(人)

class 打五角地基类 extends 打地基类{ void 打地基( ) { “打五角地基” } }

        打五角地基类 打五角地基对象 = new 打五角地基类(); //获得一个打五角地基的对象(人)

同一个盖房子的方法。

盖房子(打地基类 打地基对象,,){

        打地基对象.打地基( );

}

多态

调用时,使用不同的对象做为参数。同一个方法在执行完成之后,可以得到不同的结果。

盖房子(打四方地基对象,,); -? 多态

盖房子(打圆地基对象,,); -? 多态

三、类和对象(语法)

3.1 关系

类和对象之间的关系。必须是从现实世界向软件世界转换的过程。

现实世界--------------->软件世界

现实中的对象---(具有相同性质的对象抽象,抽出属性和行为)--->类-----(实例化)------>对象(软件世界)

3.2 创建类(语法)

类Class是一个特殊的数据类型与int,String本质是一样的。

类中有属性和方法。 例如:学员,手机这些数据类型。

属性:就是变量。

方法:就是我们之前编写的方法。 public static void print(int i);

创建的基本语法:class就是类的关键字。

public class 类名{

}

public class A{

}

3.3 创建对象(语法) 

类是一种特殊的数据类型。使用这个类型创建的变量也称为叫对象。

所以使用类创建一个对象时,需要使用new关键字进行实例化。

对象就可以通过打点的方式,调用类型中的属性和方法。

对象名.属性;

对象名.方法();

变量的使用规则 :

1 先声明

        int i;

        A a;

2 初始化

        i = 10;

        a = new A();

3 使用

        sout(i);

        a.属性=值;

        sout(a.属性);

        a.方法();

        int x = a.方法();

class A {
    int i = 10;
    public void print(){
        System.out.println("这是A类中的一个叫print方法");
    }
}

public class Test01 {
    public static void main(String[] args) {
        //使用A类创建对象a
        A a = new A();
        a.i = 40;
        System.out.println(a.i);
        a.print();
    }
}

 3.4 专用名词

A a = new A();

        a 我们叫引用

        new A(); new是实例化,实例化:在内存中创建实例空间的过程。 实例

        实例:就是我们内存中开辟的空间。

3.5 对象的内存结构

a为储存在调用方法中的一个引用,new A();则是申请一片空间来储存A中属性和方法

 3.6 属性

属性 : 一般都是指在类中声明的变量,称为成员变量,成员属性

针对成员属性,我们也叫实例属性

成员属性:就是在类中发声明的变量。

成员属性的作用域: 是受访问修饰符影响的。属性一般使用private

private 表示私有。类内私有。表示属性只在声明的这个类中可以使用。

 3.7 方法(语法)

方法:成员方法实例方法。在类中声明的方法。

成员方法的作用域: 方法一般使用public。

public 表示公有。任意位置都可以使用。

成员方法可以用来操作成员属性

3.8 JavaBean的规范

一个类如果按JavaBean规范编写,应该具备如下三个要求:

1 默认构造方法

2 私有属性

3 公有set/get方法

 set和get方法的命名格式规范:

set和get做前缀,将属性名的首字母大写拼接。

class A {
    private int age = 10;//成员属性。私有的。可以在本类的任意位置使用。
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

public class B {

    public static void main(String[] args){
        A a = new A();
        //a.age = 24; 
        /*由于age是A类的私有变量,所以不可以通过对象来直接访问,
          但是可以通过A类中的方法来访问*/
        a.setAge(24);
        System.out.println(a.getAge());
    }

}

3.9 this 关键字

this是我们Java代码中的一个关键字。

this是在实例内部一个指向自身实例的引用。

我们使用this可以指定本类中的属性和方法。

3.10 实例属性和实例方法是属于实例的

每一个实例都有自己的实例属性和实例方法。

        每new一次都是开辟一个新空间,各个空间的属性方法互不影响。

 

四、类和对象(软件设计)

4.1 类是怎么来的

类是什么?

类是对现实世界中具有相同属性和相同方法的大量对象的抽象,并抽取相同的属性和方法。

抽象的将得到的属性和发方法使用 {} 封装起来。使用关键字  class  +名称  组成类。

例如:

class A{

        属性;

        方法

}

现实世界对象是 “万物解对象” 所有可以被描述的事物都是对象。

例如:我们做一个学员管理系统。

对现实世界中大量的学员对象,进行抽象,抽属性和方法。

类是模板

学员类{

        学号;

        姓名;

        睡觉();

        打游戏();

}

/**
 * 这是一个学员类
 */
public class Stu {
    //有学号
    private int sid;
    //有姓名
    private String sname;
    //有睡觉的方法
    public void sleep(int hours){
        System.out.println(this.sname + "晚上休息了 "+hours+" 小时!");
    }

 4.2 对象

类是模板

        手机,学员,笔记本电脑。

对象是具体的事物。

        我手下的键盘,我的同桌,我的手机。

4.3 练习:编写如下的类

1.编写手机类

public class Phone {
    private String brand;
    private int price;
    private String color;
}

2.编写汽车类

public class Car {
    //品牌
    private String type;
    //价格
    private int price;
    //跑
    public void run(int distance){
        System.out.println(this.type+"加满油能跑"+distance+"公里");
    }

3.编写狗类

public class Dog {
//    编号
    private int id;
//    品种
    private String type;
//    年龄
    private int age;
//    性别
    private String gender;

    public void sleep(){
        System.out.println("狗会睡觉");
    }
    public void eat(){
        System.out.println("狗吃骨头");
    }
    public void call(){
        System.out.println("汪汪汪");
    }
}

五、构造方法

        构造方法也是一个方法

        在类中一个特殊的方法

5.1 什么是构造方法

        一个与类同名的,并没有返回类型描述的方法,叫构造方法。

public class Stu {
    //构造方法
    public Stu(){
        System.out.println("构造方法!");
    }
}

5.2 构造方法的分类

构造方法有如下几种分类:

1 默认构造方法:一个没有参数的构造方法。

        隐式构造方法:当一个类没有编写构造方法时,系统会自动为这个提供一个默认构造方法。

2 参数化构造方法:有参数的构造方法。

tips:每一个类都有一个自己的构造方法。(一定有!就算不写jdk也会给一个隐是够在方法)

5.3 构造方法的作用 

构造方法是在对象被实例化时调用的方法。

在创建实例的过程中一定要调用构造方法来创建我们的对象。

构造方法不用我们指定。系统会根据new关键字后面的类的格式来调用对应的构造方法。

Stu s1 = new Stu();//new关键字时一定要调用构造方法。

系统会按Stu()来调用对应的构造方法。

构造方法的作用是在实例化时为类的属性进行初始化操作。

class Stu {
    //有学号
    private int sid;
    //有姓名
    private String sname;

    //有参构造
    public Stu(int sid, String sname) {
        this.sid = sid;
        this.sname = sname;
    }
}

public class Main {
    Stu s1 = new Stu(1,"张三");//new关键字时一定要调用构造方法。
}

案例:学生信息

这是先写的两个类,其中birthday是stu中的一个属性。

class Birthday {
    private int year;
    private int month;
    private int day;
    public Birthday() {
    }
    public Birthday(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //set&get
   public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    @Override
    public String toString() {
        return "Birthday{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

class Stu {
    //有学号
    private int sid;
    //有姓名
    private String sname;
    //出生日期
    private Birthday birthday ;//被构造方法初始化的属性
    //构造方法
    public Stu(){
        System.out.println("构造方法!");
        birthday = new Birthday();
    }
    //有参构造
    public Stu(int sid, String sname) {
        this.sid = sid;
        this.sname = sname;
        birthday = new Birthday();
    }
    public Stu(int sid, String sname,int year, int month, int day){
        this.sid = sid;
        this.sname = sname;
        birthday = new Birthday(year,month,day);
    }

}
    private static void demo1() {
        //第一种
        Stu stu = new Stu();
        stu.setName("张三");
        stu.setBirthday(2000,1,12);
        stu.getBirthday().setDay(1000);
        System.out.println(stu.birthday.toString());
        //第二种
        Birthday birthday = new Birthday(2000,1,2);
        stu.setBirthday(birthday);
        System.out.println(stu.birthday.toString());
    }

上述的两种赋值方式都是新开辟空间后赋值,所以两个空间并不相同,以至于不会互相影响。

六、对象创建的过程(扩展)

Stu s = new Stu(); //一个对象创建的完整过程包含二个部分  类加载  和 对象创建

对象创建过程的步骤:实例化-初始化-引用赋值

1 实例化:内存中开辟实例(Stu),并为每一个属性赋默认值。

2 初始化:调用相应的构造方法(Stu()),来完成对属性的初始化。

3 引用赋值:将实例的引用赋值给引用(s)。

七、面向对象的三大特性:封装

封装:在Java中{ }就是封装。

if(条件){

        代码      //被封装的代码  

}

封装的例子有很多,大到类小到方法无处不在。

类是对大量对象进行抽象,抽象出相同的属性和方法,将属性和方法进行封装形成类。

方法是对代码的封装。

封装的好处:

1 隐藏代码细节。使用方法时,只关心格式和作用。不关心代码实现。

2 模块化开发。可同时开发且复用率高

九、继承(语法)

9.1 继承的关键字

        记住extends!!!!

9.2 继承的格式

继承一定二个类之间的关系。

        格式:

public class 子类 extends 父类{

}

        注意!!!!

在Java中只支持单继承。一个类只能有一个直接父类

        每个人只能有一个爹!!! 类也一样

class A{
}

public class B extends A{
}

9.3 继承之后的好处

子类可以使用父类的属性和方法。

        子类可以使用父类所有的属性和方法。

        只不过,当属性使用private修饰时,表示私有。

        父类中声明的私有属性和方法,可以继承,但是不能使用。

9.4 继承关系的实现方式是什么

在Java中继承关系的实现方式: 是以为每一个子类实例配置一个其父类的实例。并使用super这个引用,从子类实例中指向父类实例。

B b = new B();  //new B(); 是要创建一个B类的实例。在创建B类实例时,发现B有父类A。就会再创建一个A类的实例。

内存展示如图:

9.5 创建两个实例(父类和子类的实例)时是先后顺序 

根据上面的图。我们发现。创建子类实例时,也一定会创建一个父类实例。

实例的创建过程。一定要调用类的构造方法

父类与子类之间的实例的创建顺序:先创建好父类实例,再创建好子类实例。

父类与子类构造方法的调用顺序:先调用子类构造方法,在子类构造方法的第一行调用父类构造方法。

示例代码:

class A {
    private int i;
    public A() {
        System.out.println("A类默认构造方法!");
    }
    public void print(){
        System.out.println("A.print()");
    }
}

public class B extends A{
    public B() {
        System.out.println("B类默认构造方法!");
    }
    public static void main(String[] args) {
        B b = new B();
        b.print();//调用父类的方法。
    }
}

输出结构:

A类默认构造方法!

B类默认构造方法!

A.print()

9.6 this 和super

this是一个在实例内部指向其自身实例的引用。

super是一个在子类实例内部指向其父类实例的引用。

(1) this

就三种用法

        1 this() 在构造方法内部引用自身其他构造方法的格式。

        2 this.属性 调用自身属性的格式

        3 this.方法() 调用自身方法的格式

(2) super

就三种用法

        1 super() 在子类构造方法的第一行,调用父类构造方法的格式。

        2 super.属性 调用父类属性的格式

        3 super.方法() 调用父类方法的格式。一般这个格式会在方法重写中出现。

示例代码:

class A {
    private int i;

    public A() {
        System.out.println("A类默认构造方法!");
    }
    public A(int i){
        this.i = i;
        System.out.println("A类有参构造方法!");
    }

    public void print(){
        System.out.println("A.print()");
    }
}


public class B extends A{
    public B() {
        System.out.println("B类默认构造方法!");
    }
    public B(int i){
        super(i);//向父类构造方法传参
        System.out.println("B类有参构造方法!");
    }

    public static void main(String[] args) {
        B b = new B();
        b.print();//调用父类的方法。

	   B b1 = new B(10);

    }
}

 9.7 方法重写

方法重写:在父类与子类有相同的方法。这二个方法就叫方法重写。

class A {
    public void print(){
        System.out.println("A.print()");
    }
}

public class B extends A{
    public void print(){
        System.out.println("B.print()");
    }
    //在子类(B)中重写了父类(A)继承过来的print方法。
}

当子类调用被重写的方法时,就近原则:先找到哪一个方法就调用哪一个方法

(1) 检查方法是否重写的注解

注解:当@Override报红就表示重写代码有问题

@Override
public void print(){
    super.print();//调用父类的print()方法。
    System.out.println("B.print()");
}

(2) 方法重载

方法重载:同类同名不同参

例如:println()这个方法

同类:同一个类中可以使用的方法。 不是同一个类中声明的方法。(子类从父类继承的方法就可以重载)

9.8 练习

1. 编写父类(Person)

        有属性:姓名;

        有方法:喊到(){

        sout("大家好!我是XXXX");

}

2. 编写子类(Student)

        有属性:学号和姓名;

        有方法:喊到(){

        sout("大家好!我是XXXX");

        sout("我的学号是XXX!");

}

class Person {
    private String name;
    public Person(){
    }
    public Person(String name) {
        this.name = name;
    }
    public void call(){
        System.out.println("大家好!我是"+this.name);
    }
}

public class Student extends Person{
    private int sid;
    public Student() {
    }
    public Student(String name, int sid) {
        super(name);
        this.sid = sid;
    }
    @Override
    public void call(){
        super.call();
        System.out.println("大家好!我是"+this.getSid());
    }
}

public static void main(String[] args) {
    Student s1 = new Student();
    s1.setSid(1);
    s1.setName("张三");
    s1.call();
}

十、面向对象语言三大特点:继承(软件工程

10.1 父类是怎么来的

(1) 父类的概念:

类是对大量对象的抽象。

父类对大量子类的抽象。抽的是相同的属性和方法。

(2) 子类和父类的区别

父类中保存了所有子类共性的属性和方法。

子类中自己的特性的属性和方法。

父类更通用。子类更具体

10.2 继承的使用时机

当我们发现有很多的类,有相同的属性和方法,就可以考虑使用继承。

10.3 类的继承

(1) 判断条件:

is-a  是一个。

必须满足  子类    一个父类。  子类 is-a 父类

(2) 类之间的关系

1 is-a             是一个    继承    子类是一个父类

2 has-a          有一个    组合    类的属性

3 use-a          用一个    依赖    方法的参数

(3) 示例

把下面的四个类的关系整理清楚:

司机        车         BMW         发动机

关系:

BMW    is-a       

车         has-a    发动机

司机     use-a     车

class 司机{
	public void 工作(车 车对象){
		车对象.跑();
}
}


class 车{
	private 发动机  发动机对象;
}


class BMW extends 车{
}


class 发动机{
}

10.4 何时使用方法重写

当发现从父类继承的方法,在子类中不适用时。就可以在子类中对这个方法进行重写操作。

10.5 继承和方法重写的意义

        在面向对象语言特性中:封装,继承,多态是三大特性。

其中封装和继承都是为了实现多态服务的。

封装的目的是为了能获到,属性,方法

继承的目的是在不修改源文件的情况下,可以实现对功能的修改。

依据"开放-封闭"原则对扩展开放,对修改关闭。

        所以当有一个类,中的方法需要进行更新时。我们应该扩展一个子类。在子类中重写这个方法。

        继承和方法重写真正的目的是在不修改源文件的情况,扩展一个子类实现对父类的修改。

十一、练习:员工分类

Employee类

Employee:这是所有员工总的父类,

属性:员工的姓名name,员工的生日月份month)。

方法:double getSalary(int month) 根据参数月份来确定工资,如果该月员工过生日,则公司会额外奖励10000元。

实现代码:

public class Employee {
    private String name;
    private int month;
    public Employee() {
    }
    public Employee(String name, int month) {
        this.name = name;
        this.month = month;
    }
    /**
     * 计算员工当月工资的方法
     * @param month 发工资的月份
     * @return 如果当月员工过生日就返回10000。否则返回0
     */
    public double getSalary(int month){
        if(this.month == month){
            return 10000;
        }else{
            return 0;
        }
    }
}

SalariedEmployee类

SalariedEmployee:Employee的子类,拿固定工资的员工。

属性:月薪monthlySalary

实现代码:

public class SalariedEmployee extends Employee{
    private double monthlySalary;
    public SalariedEmployee() {
    }
    public SalariedEmployee(String name, int month, double monthlySalary) {
        super(name, month);
        this.monthlySalary = monthlySalary;
    }
    @Override
    public double getSalary(int month) {
        return super.getSalary(month)+this.monthlySalary;
    }
}

HourlyEmployee类

HourlyEmployee:Employee的子类,按小时拿工资的员工,每月工作超出160小时的部分按照1.5倍工资发放。

属性:每小时的工资(hourlySalary、每月工作的小时数hours

实现代码:

public class HourlyEmployee extends Employee{
    private double hourlySalary;
    private int hours;
    public HourlyEmployee() {
    }
    public HourlyEmployee(String name, int month, double hourlySalary, int hours) {
        super(name, month);
        this.hourlySalary = hourlySalary;
        this.hours = hours;
    }
    @Override
    public double getSalary(int month) {
        if(this.hours >= 160) {
            return super.getSalary(month) + 160*hourlySalary + (hours-160)*hourlySalary*1.5;
        }else{
            return this.hourlySalary*this.hours+super.getSalary(month);
        }
    }

SalesEmployee类 

SalesEmployee:Employee的子类,销售人员,工资由月销售额和提成率决定。

属性:月销售额sales)、提成率commission

实现代码

public class SalesEmployee extends Employee{
    private double sales;
    private double commission;
    public SalesEmployee() {
    }
    public SalesEmployee(String name, int month, double sales, double commission) {
        super(name, month);
        this.sales = sales;
        this.commission = commission;
    }
    @Override
    public double getSalary(int month) {
        return super.getSalary(month)+this.sales*this.commission;
    }
}

BasePlusSalesEmployee类

BasePlusSalesEmployee:SalesEmployee的子类,有固定底薪的销售人员,工资由底薪加上销售提成部分。

属性:底薪(baseSalary)。

实现代码

public class BasePlusSalesEmployee extends SalesEmployee{
    private double baseSalary;
    public BasePlusSalesEmployee() {
    }
    public BasePlusSalesEmployee(String name, int month, double sales, double commission, double baseSalary) {
        super(name, month, sales, commission);
        this.baseSalary = baseSalary;
    }
    @Override
    public double getSalary(int month) {
        return super.getSalary(month)+baseSalary;
    }

十三、多态(语法)

多态就是一个面向对象语言中的使用方法。

13.1 多态最基础的使用方式

多态使用最基础的结构:

父类引用指向子类实例。

父类 引用 = new 子类();

13.2 多态的多在哪里

多态最表面的理解 ,就是多种形态。

因为父类引用与子类实例 之间 是一对多的关系。

所以同一个父类引用,可以指向多个不同的子类实例。

代码示例:

A a ;//这个a的引用,可以指向三种不同的实例。
a = new C();
a = new B();
a = new A();

13.3 多态调用方法的限制

当父类引用指向子类实例时,父类引用可以打点调用哪些方法?

1 只能调用在父类中声明过的方法。 因为引用是一个父类的类型。

2 可以调用父类中的方法。

3 子类重写的方法。

十四、多态的一般使用格式

使用父类引用做为方法的形参。

使用不同子类实例做为方法的实参。

class A {
    public void dis(){
        System.out.println("A.dis()!");
    }
}

class B extends A{
    @Override
    public void dis() {
        System.out.println("B.dis()!");
    }
}

class C extends A{
    @Override
    public void dis() {
        System.out.println("C.dis()!");
    }
}

public class Test {
    public static void dis(A a){
        a.dis();
    }
    public static void main(String[] args) {
        dis(new A());//A a = new A();
        dis(new B());//A a = new B();
        dis(new C());//A a = new C();
}

十五、多态练习:学校打印老师信息

学校老师(Teacher):每位老师都有打印信息的方式

老师有姓名(name)、年龄(age)、工资(salary)

老师还有外语老师、计算机老师、注册会计老师

外语老师(LanaguageTeacher)有外语语种(languages),外语等级(grade)

计算机老师(ComputerTeacher)有计算机语种(languages),项目职务(post)

注册会计老师(AccountantTeacher)有注册会计师证(id,保存证件编号就可以),注册会计师时间(date)

写一个学校类(School)。学校类负责打印每位教员的信息。

Teacher

public class Teacher {
    private String name;
    private int age;
    private double salary;
    public Teacher() {
    }
    public Teacher(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
}

School

public class School {
    public void print(Teacher teacher){
        System.out.println(teacher);
    }
}

LanaguageTeache

public class LanaguageTeacher extends Teacher{
    private String languages;
    private int grade;
    public LanaguageTeacher() {
    }
    public LanaguageTeacher(String name, int age, double salary, String languages, int grade) {
        super(name, age, salary);
        this.languages = languages;
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "LanaguageTeacher{" +
                "languages='" + languages + '\'' +
                ", grade=" + grade +
                "} " + super.toString();
    }
}

ComputerTeacher

public class ComputerTeacher extends Teacher{
    private String lanaguages;
    private String post;
    public ComputerTeacher() {
    }
    public ComputerTeacher(String name, int age, double salary, String lanaguages, String post) {
        super(name, age, salary);
        this.lanaguages = lanaguages;
        this.post = post;
    }

    @Override
    public String toString() {
        return "ComputerTeacher{" +
                "lanaguages='" + lanaguages + '\'' +
                ", post='" + post + '\'' +
                "} " + super.toString();
    }
}

main函数

public static void main(String[] args) {
    LanaguageTeacher teacher1 = new LanaguageTeacher();
    teacher1.setGrade(8);
    teacher1.setLanguages("英语");
    teacher1.setAge(25);
    teacher1.setSalary(888888);
    teacher1.setName("张老师");

    ComputerTeacher teacher2 = new ComputerTeacher();
    teacher2.setAge(25);
    teacher2.setSalary(9999999);
    teacher2.setName("孙老师");
    teacher2.setLanaguages("Java");
    teacher2.setPost("项目经理");


    School school = new School();
    school.print(teacher1);
    school.print(teacher2);
}

十六、修饰符final关键字

final修饰符只能修饰到如下几个地方:

1 final 变量  =》表示这是一个常量值。不可以被修改

2 final 方法  =》表示这个方法不可以被重写。不可以被修改。

3 final  =》表示这个类不可以被继承。不可以被修改。

常量命名的规范:

1 全大写

2 每个单词之间用_分隔

例如:final int DAY_OF_YEAR = 365;

十七、修饰符static

static 中文名 静态

17.1 static可以修饰的4个地方

1 代码块 静态代码块

2 属性 静态属性

3 方法 静态方法

4 内部类 静态内部类(淘汰了)

17.2 静态代码块

static{
	代码块;
}

静态代码块一定是写在类中的。

静态代码块是在类加载时被执行的。而且只会执行一次。

静态代码块的作用是为了给静态属性进行初始化操作。

示例代码:

public class A {
    static {
        System.out.println("静态代码块!");
    }
    public A() {
        System.out.println("A类的构造方法!");
    }
    public static void main(String[] args) {
        new A();
        new A();
    }
}

17.3 静态属性

为实例属性增加static修饰符之后。属性就变成了静态属性。

public class A {
    private static int i ;//静态属性
    private int j ;//实例属性
}

实例属性是属于每一个实例的。第一个实例都有自己的实例属性。实例属性是使用构造方法进行初始化。

静态属性是属于当前整个类的。这个类的每一个实例都共用同一个静态属性。

静态属性是在类加载时就创建了。使用静态代码码进行初始化操作。

静态方法的使用方法有两种:

1 对象名.静态属性

2 类名.静态属性

17.4 静态方法

作用范围:

静态方法属于当前整个类的。

使用 类名.静态方法() 调用。

使用静态方法来操作静态属性。

使用案例:

一般算法类的公式,都会写成静态方法。

Arrays.sort();给数组进行排序。

十八、单例模式

18.1 什么是单例模式

单例模式:表示一个类只能去创建一个实例。

class A{

}

A a1 = new A();

A a2 = new A();

18.2单例模式的第一步:私有化构造方法

第一步:私有构造方法。构造方法就只能在类内调用。

所以:实例只能在类内创建

第二步:在类内创建实例。

第三步:让外部通过本类的静态方法来获取实例。

18.3 饿汉模式

public class SingletonA {
    //第二步:本类中创建自己的静态实例。
    private static SingletonA singletonA = new SingletonA();
    //第一步:私有构造方法
    private SingletonA() {
    }
    //第三步:静态方法,通过 类名.getSingletonA();
    public static SingletonA getSingletonA() {
        return singletonA;
    }
}

18.4 懒汉模式

public class SingletonB {
    private static SingletonB singletonB;
    private SingletonB() {
    }
    public static SingletonB getSingletonB() {
        if(singletonB == null) {
            singletonB = new SingletonB();
        }
        return singletonB;
    }
}

十九、封装、继承、多态

19.1 封装

封装就是将代码包装起来。  { }

在面向对象设计与分析中。封装最核心的目的是得到 类和方法。

方法:实现某一功能的代码的封装。

类:类是对大量对象的封装。封装相同的属性和方法。

父类:父类是对大量子类的封装。封装相同的属性和方法。

软件开发原则:将针对需求改变时,代码变化部分  与  代码不变的部分  分开  封装。

最经典的应用:dao层。数据库连接对象的工具类。

数据封装:使用private,public 访问修饰符。实现对数据的封装。

19.2 继承

public class B extends A{

}

B是子类。A是父类。

子类可以使用父类的属性和方法。(语法)

在面向对象的分析与设计中:

子类是对父类的修改。子类是对父类功能的扩展。

子类对父类进行修改和扩展时,需要依赖 方法重写

在软件开发的原则:

is-a 子类是一个父类。

里氏替换原则 : 所有使用父类的地方,都可以使用其子类进行替换。

19.3 多态

多态只是一种语言特性。是一种特殊的使用方式。

多态:

父类引用 指向  子类实例

A a  =  new  B();

当前多态格式可以调用的方法有:

1 父类的方法

2 子类重写的方法

特别注意:子类自己的方法是不能被父类引用所调用的。

多态使用的一般格式:

1 父类引用做形参

public static void print(Person p){
    System.out.println( p.toString() );
}

2 子类实例做实参

Stu s = new Stu();
Tea t = new Tea();

print(s);//传参是学员对象。print方法中调用学员类的toString()
print(t);//传参是教员对象。print方法中调用教员类的toString()

二十、修饰符abstract

20.1 abstract可以修饰2个位置

abstract可以修饰的位置:

1 方法       抽象方法

2 类           抽象类

20.2 抽象方法

抽象方法是一个没有方法体的方法。只有方法的原型。

实例方法:

public void print(int i){
  sout(i);
}

抽象方法:

1 使用abstract修饰

2 没有方法体,只有原型。

        public abstract void print(int i);

我们认为抽象方法是一个没有写完的方法。就不可以执行。

抽象方法一定需要被重写

20.3 抽象类

(1) 什么是抽象类

一个被abstract修饰符修饰的类就是一个抽象类。

        public abstract class A{ }

有抽象方法的类,必须是一个抽象类。

(2) 抽象类的使用方法

我们认为抽象类是一个没有完成的类。就不可以被实例。

抽象类一定要被继承

20.4 抽象类与抽象方法的使用方法

抽象类要继承

抽象方法要重写

A类(抽象类):

public abstract class A {
    public void print(){
    }
    public static void dis(){
    }
    public abstract void info();
}

B类:

public class B extends A{
    @Override
    public void info() {
    }
}

二十一、abstract 的使用场景

面向对象语言最合性的特性是:多态。

父类   引用  =  new   子类();

这个引用可以调用的方法是:

1  父类的方法

2  子类重写方法

都是在父类中声明的。

条件1:多态时方法必须在父类中声明

条件2:父类没有方法的实现

因为很多父类本身就是一个抽象的概念

因为很多父类本身就是一个抽象的概念。

三角形,矩形,圆形都是具体的实例。

图形父类就是一个抽象的概念。

二十二、 访问修饰符

private,public都是访问修饰符。

在Java中一共有四个访问级别。但是只有三个访问修饰符关键字。

级别关键字本类同包的其他类不同包的子类不同包的非子类
公有publicYYYY
保护protectedYYY
默认(default)YY
私有privateY

二十三、枚举(enum关键字)

enum也是类声明关键字。所以enum的级别与class是一致的。

23.1什么是枚举

枚举也是一种特殊的数据类型

枚举也是一种特殊的类

枚举就是一个有固定实例数量的类

例如计算机三原色RGB。交通信号灯颜色。季节。月份。

23.2枚举的定义格式

public enum RGB {
    RED,GREEN,BLUE;
}

我们定义了一个枚举类型:RGB。

在这个类型中,有三个实例。分别是RED,GREEN,BLUE;

23.3 枚举使用的格式

枚举中第一个值,都是枚举的一个实例。

public class Test {
    public static void main(String[] args) {
        RGB rgb1 = RGB.RED;
        RGB rgb2 = RGB.BLUE;
        RGB rgb3 = RGB.GREEN;
    }
}

23.4 枚举本质上就是一个Java类

枚举是在JDK5才加入的新特性。

在JDK5之前。我们都是使用Java类的方式实现枚举的要求。

这是在JDK5之前,一个类只有三个实例的标准写法。

public class RGBClass {
    public final static RGBClass R = new RGBClass();
    public final static RGBClass G = new RGBClass();
    public final static RGBClass B = new RGBClass();
    private RGBClass() {
    }
}

在这个代码的基础上。我们把固定的代码删掉,会得到什么?

public class RGBClass {
    R;
    G;
    B;
}

从用法上来看,枚举就是自带一些固定代码的特殊的类的用法

23.5 如何使用枚举类型

(1) 枚举一般配合switch一起使用

RGB rgb ;
switch (rgb1){
    case RED:
        System.out.println("red");
        break;
    case BLUE:
        System.out.println("blue");
        break;
    case GREEN:
        System.out.println("green");
        break;
}

(2) 当一个方法的参数是一个枚举类型时

问:一个公司只有7个部门。用什么类型来表示这7个部门。

1 使用编号,int,分别1-7

        编写方法时。参数就是int。 public void print(int i){}

        int数据类型合法的取值范围要比1-7大。

        业务规范要求1-7的取值。但是语法要求合法的int类型太多了。

2 使用枚举。使用一个有7个实例的枚举。

        编写方法时,参数是枚举类型。 public void print(RGB rgb){}

        当RGB做为参数时,合法的取值有3个。RGB.RED , RGB.GREEN , RGB.BLUE;

23.6 枚举可以有属性和方法

枚举就是一个Java类。

public enum RGB {
    RED,GREEN,BLUE;
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
RGB.RED.setName(“红色”);

23.7 枚举中国可以有构造方法

在JDK5之前的方式如下:

public class RGBClass {
    private String name;
    public final static RGBClass R = new RGBClass("红");
    public final static RGBClass G = new RGBClass("绿");
    public final static RGBClass B = new RGBClass("蓝");
    public RGBClass(String name) {
        this.name = name;
    }
}

删掉统一可以不写的内容后

public class RGBClass {
    private String name;
    R ("红");
    G ("绿");
    B ("蓝");
    public RGBClass(String name) {
        this.name = name;
    }
}

按格式转换:枚举应该如下:

public enum RGB {
    RED("红"),
    GREEN("绿"),
    BLUE("蓝");
    private String name;
    RGB(String name) {
        this.name = name;
    }
}

二十四、接口(interface)

24.1 接口的声明

接口interface关键字。与class,enum是同级。

public interface 接口名{

}

24.2 接口中的内容

JDK1.8之前

接口中只能写二种内容:

1 public static final int I; //公有静态常量。

2 public abstract void dis(); //公有抽象方法

JDK1.8之后

接口中又多了两种内容:

1  公有静态方法

2  公有实现方法(实例方法)(有方法体可以直接使用的方法)

static void print(){
    System.out.println("公有静态方法!");
}
default void info(){
    System.out.println("公有实例方法!");
}

24.3 接口的使用

接口中有抽象方法,所以接口本身不能被实例化。

接口的使用需要与类配合。与接口配合一起使用的类,我们叫实现类。

需要使用实现类。实现接口中的所有抽象方法。

实现的关键字:implements

public class 实现类 extends 父类 implements 接口列表{

方法重写(){ }

}

1实现类可以在继承一个父类的同时,实现接口。

2 使用implements 关键字实现接口。

3 Java只支持单继承,但是可以支持多实现。

public class Impl01 implements Inter01,Inter02{
}

4 实现类应该实现接口中所有抽象方法。

public class Impl01 implements Inter01{
    @Override
    public void dis() {
        System.out.println("实现类Impl01给出的方法实现!");
    }
}

24.4 接口与实现类之间也支持多态

类的多态:

父类 引用 = new 子类( );

接口的多态:

接口 引用 = new 实现类( );

接口的引用打点可以调用实现类的重写方法

public class Test {
    public static void main(String[] args) {
        Inter01 inter01 = new Impl01();
        inter01.dis();
        inter01.info();
    }
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修贤323

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值