美文网首页
Java 面向对象入门

Java 面向对象入门

作者: 吃啥呀 | 来源:发表于2020-11-02 12:42 被阅读0次

目标读者

了解 Java 基本数据类型
掌握 Java 输出、for、if 等基本语法
熟练应用函数,了解函数重载等基本知识
熟练使用 IntelliJ IDEA

权限修饰符

类、成员变量、成员方法最前面的单词叫做权限修饰符,表明从项目的哪些地方可以访问这个类、变量、方法。具体见下表:

是否能访问 同一文件 同一包 子类 不同类
public
protected
default(缺省)
private

举例:

类:老师(Teacher)

特征:成员变量:有姓名(name),年龄(age)等属性

行为:成员方法:讲课(teaching)、布置作业(assignWork)

Class(类)

语法规则:

// public class xxx
// xxx 自己给类取的名字
public class Teacher{
    
    // 成员变量
    String name;
    int age;
    
    // 构造方法 --- 获得对象的方法
    // 与类同名,无返回值
    // 在用该类实例化一个对象的时候需要被调用
    // 类默认自带无参构造函数
    Teacher(){
        
    }
    
    // 有参构造函数
    // 一般是为成员变量赋值
    Teacher(String name){
        ......
    }
    
    // 普通成员方法
    private void teaching(){
        ......
    }
    
    void assignWork(){
        ......
    }
}

思考:

1.teaching是否可以获得值 name 或者 age?

根据变量的作用域可知,是可以的。

举例:

有一个老师,她叫twter,年龄是18岁

有一个老师,她叫冠中,年龄是5岁

有一个老师,她叫昕姐,年龄是3岁

对象

对象是描述客观事物的一个实体,由类实例化来生成。

普通的成员变量和成员方法都是属于这个对象的。

即这个对象诞生,属于这个对象的成员变量和成员方法才诞生。

要通过对象才能获得成员变量和成员方法。

构造方法

构造方法是类与对象的桥梁,构造方法和类同名,且没有返回值。

在构造方法内可以进行成员变量的赋值。

通过new调用构造方法可以获得类的实例化对象。

public class Teacher {

    // 成员变量
    String name;
    int age;

    // 构造方法
    // 默认自带无参
    Teacher() {

    }
    
    Teacher(String mname,int mage){
        name = mname;
        age = mage;
    }
}

public class Test {
    public static void main(String[] args) {
        // 通过new可以生成一个新的具体的类
        // 我们称之为实例化 Teacher 生成一个 Teacher 的对象
        Teacher teacher = new Teacher();
        Teacher teacher1 = new Teacher();
        // teacher 和 teacher1 不是同一个对象
        teacher.name = "twter";
        teacher.age = 18;
        
        // 执行构造函数内的语句,进行赋值
        // Teacher的实例化对象 teacher3
        // teacher3的name是twter,age是18
        Teacher teacher2 = new Teacher("twter", 18);
        Teacher teacher3 = new Teacher("greenTea", 12);
    }
}

思考:

1.如何获得一个老师,她叫绿茶,年龄是12岁。

2.有参构造函数可以写成如下形式吗?

public class Teacher {

    // 成员变量
    String name;
    int age;
    
    Teacher(String name,int age){
        name = name;
        age = age;
    }
}

this

代表“当前对象”示例

就可以区别传入的参数“name”和对象自己的“name”。

public class Teacher {

    // 成员变量
    String name;
    int age;
    
    Teacher(String name,int age){
        this.name = name;
        this.age = age;
    }
}

举例:

某个老师上课(teaching)的时候会说 name 老师在上课

成员方法

public class Teacher {

    // 成员变量
    String name;
    int age;
    
    Teacher(String name){
        this.name = name;
    }
    
    Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 普通成员方法
    void teaching() {
        System.out.println(name + "is teaching");
    }
}


public class Test {
    public static void main(String[] args) {
        Teacher teacher2 = new Teacher("twter", 18);
        Teacher teacher3 = new Teacher("sxbasubx");
        
        teacher2.teaching();
    }
}

思考:

1.某个老师布置作业(assingWork)的时候会说老师布置了 x 道作业

public class Teacher {

    // 成员变量
    String name;
    int age;

    Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    void assignWork(int x) {
        System.out.println(name + " assign " + x + " number of homework");
    }
}

public class Test {
    public static void main(String[] args) {
        Teacher teacher2 = new Teacher("twter", 18);
        teacher2.assignWork(2);
    }
}

2.如何保护 name 不被随意修改?

public class Teacher {

    // 成员变量
    private String name;
}

但是我在main函数里想要获得老师对象的 name?

public class Teacher {

    // 成员变量
    private String name;
    
    public String getName() {
        return name;
    }
}

封装

要访问该类的代码和数据,必须通过严格的接口控制。

外部可以修改name,比如在main函数里可以修改name,但是必须按照规定的方式来。

public class Teacher {

    // 成员变量
    private String name;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
}

疑惑:那这和我直接用 public 修饰 name 变量有什么区别呐?

课堂作业

类:小饼干(cookie)

这个小饼干是由巧克力和抹茶组成的!

成员变量:价格(price),小饼干中巧克力的价格(priceOfChocolate),小饼干中抹茶的价格(priceOfTea)

price = priceOfChocolate + priceOfTea

我想要在main函数里实例化3个不同价格的巧克力和不同价格抹茶的组成的小饼干对象。

Coockie priceOfChocolate priceOfTea
coockie1 12.4 121
coockie2 13 423
Coockie3 12937 1213.2

根据 price 理解封装的好处。

想要统计生成的饼干数量?

这个信息应该是凌驾于对象上的

static

用static修饰的成员变量和成员方法不再依赖于对象,而是属于类本身。可以直接通过类名获得

1.静态方法里可以使用静态成员变量吗?

2.普通(非静态)方法里可以使用静态成员变量吗?

3.普通方法里可以使用普通成员变量吗?

4.静态方法里可以使用普通成员变量吗?

5.普通方法里可以调用静态方法吗?

6.静态方法里可以调用静态方法吗?

7.静态方法里可以调用普通方法吗?

yes yes yes no yes yes no

package xyz.chenshuyusc.course2;

public class Coockie {
    private double price;
    private double priceOfChocolate;
    private double priceOfTea;

    private static int count; // = 0

    public Coockie() {
        ++count;
    }

    public Coockie(double priceOfsth, boolean isTea) {
        if (isTea) {
            this.priceOfTea = priceOfsth;
        } else {
            this.priceOfChocolate = priceOfsth;
        }
        this.price = this.priceOfTea;
        ++count;
    }

    public Coockie(double priceOfTea){
        this.priceOfTea = priceOfTea;
        this.price = this.priceOfTea;
    }

    public double getPrice() {
        return price;
    }

    public double getPriceOfChocolate() {
        return priceOfChocolate;
    }

    public double getPriceOfTea() {
        return priceOfTea;
    }


    public void setPriceOfChocolate(double priceOfChocolate) {
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public void setPriceOfTea(double priceOfTea) {
        this.priceOfTea = priceOfTea;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public static int getCount() {
        return count;
    }

    protected void setPrice(double price) {
        this.price = price;
    }
}

举例子:

类:甜甜的小饼干

这个小饼干是由巧克力和抹茶组成的甜味小饼干!

成员变量:价格(price),小饼干中巧克力的价格(priceOfChocolate),小饼干中抹茶的巧克(priceOfTea),糖(priceOfSugar)

类:咸咸的小饼干

这个小饼干是由巧克力和抹茶组成的咸味小饼干!

成员变量:价格(price),小饼干中巧克力的价格(priceOfChocolate),小饼干中抹茶的巧克(priceOfTea),盐(priceOfYan)

看起来和之前的小饼干很重合!!!

extends ( 继承 )

子类继承父类的特征和行为。

即甜甜的小饼干继承小饼干,就获得了小饼干中非private的成员变量和成员方法。

但甜甜的小饼干又比小饼干多了priceOfSugar。

public class Coockie {
    private double price;
    private double priceOfChocolate;
    private double priceOfTea;

    public Coockie() {
    }

    public Coockie(double priceOfsth, boolean isTea) {
        if (isTea) {
            this.priceOfTea = priceOfsth;
        } else {
            this.priceOfChocolate = priceOfsth;
        }
        this.price = this.priceOfTea;
    }

    public double getPrice() {
        return price;
    }

    public double getPriceOfChocolate() {
        return priceOfChocolate;
    }

    public double getPriceOfTea() {
        return priceOfTea;
    }


    public void setPriceOfChocolate(double priceOfChocolate) {
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public void setPriceOfTea(double priceOfTea) {
        this.priceOfTea = priceOfTea;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    protected void setPrice(double price) {
        this.price = price;
    }
}


public class SugarCoockie extends Coockie {
    private double priceOfSugar;

    public SugarCoockie(double priceOfsth, boolean isTea) {
        super(priceOfsth,isTea);
    }
    
    public double getPriceOfSugar() {
        return priceOfSugar;
    }

    public void setPriceOfSugar(double priceOfSugar) {
        setPrice(getPrice() - this.priceOfSugar + priceOfSugar);
        this.priceOfSugar = priceOfSugar;
    }
}

子类的构造方法必须调用父类的构造方法。

思考:如果要通过子类实例化对象,父类可以没有构造函数吗?

Override

子类中包含跟父类方法签名一样的方法,父类的方法会被覆盖掉,我们就说该方法被重写。如需调用父类原有的成员方法,可使用 super 关键字。

public class Coockie {
    protected double price;
    protected double priceOfChocolate;
    protected double priceOfTea;

    public Coockie() {
    }

    public Coockie(double priceOfsth, boolean isTea) {
        if (isTea) {
            this.priceOfTea = priceOfsth;
        } else {
            this.priceOfChocolate = priceOfsth;
        }
        this.price = this.priceOfTea;
    }

    public double getPrice() {
        return price;
    }

    public double getPriceOfChocolate() {
        return priceOfChocolate;
    }

    public double getPriceOfTea() {
        return priceOfTea;
    }


    public void setPriceOfChocolate(double priceOfChocolate) {
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public void setPriceOfTea(double priceOfTea) {
        this.priceOfTea = priceOfTea;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public static int getCount() {
        return count;
    }

    protected void setPrice(double price) {
        this.price = price;
    }
}


public class SugarCoockie extends Coockie {
    private double priceOfSugar;

    @Override
    public void setPriceOfChocolate(double priceOfChocolate) {
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfSugar + this.priceOfChocolate + this.priceOfTea;
    }

    @Override
    public void setPriceOfTea(double priceOfTea) {
        super.setPriceOfTea(priceOfTea);
        this.price = this.priceOfSugar + this.priceOfChocolate + this.priceOfTea;
    }

    public double getPriceOfSugar() {
        return priceOfSugar;
    }

    public void setPriceOfSugar(double priceOfSugar) {
        this.priceOfSugar = priceOfSugar;
        this.price = this.priceOfSugar + this.priceOfChocolate + this.priceOfTea;
    }

}

Builder 设计模式

当一个类需要初始化的成员变量比较多、比较复杂时,仅使用构造方法来初始化对象就显得冗余且难以理解,这里介绍一个经典的解决办法:利用 Builder 设计模式实现链式调用来获取对象。

package xyz.chenshuyusc.course2;

public class Coockie {
    double price;
    double priceOfChocolate;
    double priceOfTea;
    Choc choc = new Choc();

    public Coockie() {
    }

    public Coockie(double priceOfChocolate, double priceOfTea,Choc choc) {
        this.choc = choc;
        this.priceOfTea = priceOfTea;
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfTea + this.priceOfChocolate;
    }
    
    public double getPrice() {
        return price;
    }

    public double getPriceOfChocolate() {
        return priceOfChocolate;
    }

    public double getPriceOfTea() {
        return priceOfTea;
    }


    public void setPriceOfChocolate(double priceOfChocolate) {
        choc.price = priceOfChocolate;
        this.priceOfChocolate = priceOfChocolate;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

    public void setPriceOfTea(double priceOfTea) {
        this.priceOfTea = priceOfTea;
        this.price = this.priceOfChocolate + this.priceOfTea;
    }

}

public class CoockieBuilder {

    private Coockie coockie = new Coockie();

    public CoockieBuilder priceOfTea(double priceOfTea) {
        coockie.setPriceOfTea(priceOfTea);
        return this;
    }

    public CoockieBuilder priceOfChocolate(double priceOfChocolate) {
        coockie.setPriceOfChocolate(priceOfChocolate);
        return this;
    }
}

package xyz.chenshuyusc.course2;

public class TestCoockie {
    public static void main(String[] args) {

        Coockie coockie = new CoockieBuilder()
                .priceOfChocolate(1213)
                .priceOfTea(1293)
                .build();

        CoockieBuilder coockieBuilder = new CoockieBuilder();
        coockieBuilder = coockieBuilder.priceOfTea(1231.2);
        coockieBuilder = coockieBuilder.priceOfChocolate(21);
        coockieBuilder = coockieBuilder.priceOfTea(213);


        System.out.println(coockie.getPriceOfChocolate());
        System.out.println(coockie.getPriceOfTea());
        System.out.println(coockie.getPrice());
    }
}

相关文章

  • 标签墙

    java入门程序 超级容易理解!!!Java的面向对象思想———类与对象。

  • 阶段 1:Java语言基础

    一. Java 编程入门 二. Java面向对象编程 三. Java语言高级特性

  • JavaScript面向对象--对象定义

    1.理解JavaScript面向对象 面向对象是高级语言程序员入门必修的课程,但是常用的面向对象都是java、C#...

  • Java 基础

    Java 基础01Java开发入门 Java 基础02Java编程基础 Java 基础03面向对象 Java 基础...

  • 不好好学代码 你连当韭菜都不够格

    java零基础入门-面向对象篇(十一) 数据流动与包装类 面向对象学了这么多,满脑子都是对象,面向对象千好万好,可...

  • Java入门:面向对象

    面向对象 面向对象(Object Oriented)是一种新兴的程序设计方法,或者是一种新的程序设计规范(para...

  • Java 面向对象入门

    目标读者 了解 Java 基本数据类型掌握 Java 输出、for、if 等基本语法熟练应用函数,了解函数重载等基...

  • spring boot+scala编写web接口

    本人是Java开发者,有面向对象的基础,而Scala也是面向对象的语言,学习后可快速入门。通过学习Scala的面向...

  • Java8高级开发视频教程

    学过前面的课程Java入门和Java面向对象编程之后,相信你已经熟练的掌握了面向对象中的各种概念,是否会对这些知识...

  • 阿里20年老兵总结出这份633页Java从入门到项目实战文档

    《Java 从入门到项目实战》是一本Java入门书,详细介绍了Java语言面向对象程序设计中的Java核心技术和编...

网友评论

      本文标题:Java 面向对象入门

      本文链接:https://www.haomeiwen.com/subject/epfmvktx.html