zoukankan      html  css  js  c++  java
  • Java入门(七)之面向对象-划重点

    Java入门(七)之面向对象-划重点

    0. 面向对象的概念

    0.1 面向对象和面向过程

    • 面向对象是一种软件开发方法,这种方法可以将现实中的事物抽象出来,让我们的编程模型化。

    • 面向过程也是一种软件开发方法,它需要我们通过具体的,流程化的方式去解决问题

    • 打个比方,我们现在要吃个饭。

      • 可能我们会自己煮,所以要先去买个菜,然后洗菜切肉淘米,煮饭炒菜煲汤,然后吃掉,洗碗。这个叫做面向过程
      • 可能我们会去饭店,我们只需要点菜,然后等东西上来,吃掉,然后就付钱走人。我们不用理会菜是从哪里买的,也不用理会饭是怎么做的,吃完不用洗碗。这个叫做面向对象
    • 再举个程序的例子吧

      • C语言就是一个典型的面向过程的语言,我们在写程序的时候,会在main函数中写上我们的主程序,可能会调用其他的函数,甚至是其他文件的函数。

        #include <stdio.h>
        
        //使用C语言生成正方形
        int main(){
            printRect(3);
        }
        
        void printRect(int size){
            for(int i = 0;i<size;i++){
                for(int j = 0;j<size;j++){
                    printf("*");
                }
                printf("
        ");
            }
        }
        
      • Java使用的是面向对象编程,所以我们所有的编程都围绕着类来进行。我们不能直接调用方法,而是应该先创建实例,然后再调用实例的方法。

        public class Test(){
            
            public static void main(String[] args){
                RectUtil rectUtil = new RectUtil();
                rectUtil.printRect();
            }
        }
        
        ==============下面是另一个类======================
        //一个与矩形有关的工具类
        public class RectUtil(){
            //有一个生成矩形的方法
            public void printRect(int size){
                for(int i = 0;i<size;i++){
                    for(int j = 0;j<size;j++){
                        printf("*");
                    }
                    printf("
        ");
                }
            }
        }
        

    0.2 属性和方法

    • 在现实中,对象指的是具体某一个事物。而在程序中,我们的对象是指我们编写的系统的某一个成分。
    • 对象会包含两个内容,一个是数据,一个是动作。对象不仅能够进行操作,还能记录操作的结果。举个栗子,你会吃饭,并且吃完会变重。你的吃饭是一个动作,而体重是一个数据。
    • 众所周知,类是从对象中抽象出来的,可以说:类是对具有相同特性和行为的对象的抽象。所以,类的具体化(或者说实例化)就是对象,对象的抽象化就是类。
    • 类具有属性,我们通过属性来描述类的特性。
    • 类具有方法,我们通过方法来描述类的一些操作,我们也可以叫它函数
    • 实例化为对象,类的属性可以被赋值成为对象的数据,类的方法可以被调用成为对象的一个动作,或者说操作。
    • 类,也可以当做一种数据类型。
      • 例如:String,Date都是一个类,同时他们也可以表示字符串,时间的数据。
    • 由上面这条,我们可以明确一点,类里面的属性可以是其他的类。
      • 例如:一个电脑类,它的属性可以有CPU,显卡,显示屏,而这些同样可以抽象为类,同时它们又是电脑类的属性之一。

    1. 面向对象的特征

    1.1 对象唯一

    • 每一个对象,都是唯一的,会有一个唯一的标识,就像C语言中的指针,存储着变量的地址,类实例化成对象后,会有一个唯一的地址存放对象。

    1.2 抽象性

    • 指的就是将具有相同特性和行为的对象抽象成类。

    1.3 三大特性——继承、封装、多态

    1.3.1 继承

    • 继承指的是从已经存在的类中继承到它的属性和方法,这样可以减少代码的重复。
    • 父类:指的是被继承的那个类
    • 子类:指的是继承父类的类。
    • 在Java中,所有的类继承与Object,即所有类的父类都为Object
    • 在Java中,只允许被一个类继承,目的是降低多继承带来的耦合度过高
      • 我们可以通过多个接口,拓展类的功能。

    1.3.2 封装

    • 生活中的封装指的是将东西包裹起来

      • 例如电脑机箱将内部的元件封装,我们看到的是机箱,可以使用开机按钮,而看不到内部的元件。
    • 在程序设计中,我们可以将类封装起来,只提供需要的方法接口,而不需要提供具体的实现细节。

      • 例如:我们实现一个翻译单词的类,我们需要做几件事
        1. 写一个读取单词列表的方法
        2. 写一个在单词列表中查找我们要翻译单词的方法
        3. 写一个方法整合上面两个方法,实现业务逻辑:读取单词列表 -> 查找目标 -> 返回结果
      • 而在这之中,我们只需要第三个方法就可以实现翻译单词。而另外两个方法可以不暴露出来,从而让我们代码更加健壮。
    • 封装有四个修饰符

      范围/修饰符 类的内部 包的内部 任何位置 适用 备注
      public 修饰类,成员属性,成员方法,内部类
      protected 修饰成员属性,成员方法,内部类 不能修饰类
      默认不写 修饰类,成员属性,成员方法,内部类
      private 修饰成员属性,成员方法,内部类 私有方法不能被继承
    • 封装的原则

      • 把不需要对外提供的内容都隐藏起来,把属性都隐藏起来,提供公共方法对其访问(通常使用get获取,set设置)
    • 封装的结果是存在,但是不可见

    1.3.3 多态

    • 同名的不同方法

    • 将子类对象赋值给父类变量,调用的方法为子类的方法。由此,同个类型的对象在执行同一个方法时,可以表现出多种行为特征

      • 例子:QQ群中的管理员和群成员。管理员也是群成员,所以可以说群成员是管理员的子类。
      • 当我在使用修改备注功能的时候,群成员只能修改自己的备注,而管理员可以修改其他人的备注。
      • 同理,群主也继承于群成员,但是群主有更多的权限。
    • 此时,如果你想调用父类的方法,可以使用super关键字。

    • 父类中声明为static、final的方法不能被覆盖,而且声明为final的类的所有方法不允许被覆盖。

    • 方法的重载

      • 方法的重载是另一种实现多态的方法,它指的是在类中,定义同名的方法,但是这些方法具有不同的参数类型,参数个数,则可以实现多态。
      • 使用这种方法时,当我们填入的数据类型为对应方法的类型时,就会调用该方法。
      test(int i){}
      test(String str){}
      test(int i,String str){}
      当我调用test(1)时,会自动的调用到第一个方法,而调用test("1")时,会自动调用到第二个方法。
      

    2. 继承相关

    2.1 抽象类

    • 抽象类使用abstract class关键字来定义
    • 抽象类除了不能实例化外,写法与普通类并无二致
    • 由于不能实例化,抽象类只有被继承才能使用,因此一般在设计时就会决定是否使用抽象类
    public abstract class AStudent{
        private String id;
        private String name;
        private String dept;
        
        public void study(){
            System.out.println("我在学习!");
        }
    }
    
    public class GoodStudent extends AStudent{
        public void study(){
            super().study();
            System.out.println("敲代码,进大厂!");
        }
    }
    
    public class BadStudent extends AStudent{
        public void study(){
            System.out.println("什么时候可以下课,我要去食堂抢位置了!");
        }
    }
    

    2.2 接口

    • 接口使用interface关键字来声明

    • 接口不是类,类包含属性和方法,而接口包含要实现的类

    • 接口无法被实例化,只能被实现

    • 实现

      • 接口中的方法是没有实现的,即只有方法名,没有方法的内容。
      • 我们可以理解为,这是一个空白的田字格,告诉顶上写拼音,下边写汉字,但是写什么拼音,什么汉字可以由你自己定。
    public interface Teacher [extends 这里可以继承其他接口,但是我不做示范]{
        public void teaching([这里可以写变量,但是我不做示范]);
    }
    
    public class TeacherImpl implements Teacher{
        //如果你实现了接口,那么类中必须有接口里所有的方法的实现
        public void teaching(){
            [代码内容]
        }
    }
    

    3. 多态相关

    3.1 构造方法

    • 构造方法是类的一种特殊方法,用来初始化新的对象。
      • 当我们实例化时,会写:new Student()这种写法,这里的Student为什么会有括号,因为调用了构造方法。
    • 当我们不写构造方法时,会有默认的一个无参的构造方法(无参指的是没参数)
    • 当我们写一个构造方法时,无参的构造方法会被覆盖,即此时没有默认的构造方法
      • 因此,当我们写一个有参的构造方法时,如果还想不调用构造方法,可以再写一个空白的无参构造方法
    public class test{
        //构造方法与类名同名,不用定义返回值,我们可以认为返回值为这个类。
        public test(){
            
        }
        //有参的构造方法
        public test(int i){
            
        }
    }
    
    • 由多态的性质,我们可以知道,构造方法可以有很多个,因为它本身也是一个方法,符合多态的特性。

    • 跟普通方法不同的是,它是在类被实例化的时候调用的。

      • 在没有自己写构造方法时,会默认一个无参的构造方法
      • 在写了一个构造方法时,没有默认的无参构造方法。
    • 我们可以将其应用在,需要给多个属性赋值的时候。

      • //如果没有构造方法
        Student student = new Student();
        student.id = "123456";
        student.name = "小明";
        //如果有构造方法
        Student student = new Student("123456","小明");
        student = new Student();//如果没有写无参的构造方法,此时这样写会报错
        

    课后习题

    • 尝试使用面向对象的思想进行编程,讲述一个小故事

    • 例如:

      恋爱的狮子与农夫

      ​ 狮子爱上了农夫的女儿,请求农夫把女儿嫁给他。农夫既不忍心把女儿许配给野兽,又不敢拒绝,就想出一个办法
        
        当狮子来催促的时候,农夫对他说:“我愿意把女儿嫁给你,可是我的女儿害怕你的尖牙和利爪,而且我也担心这些会伤害到她。如果你能剪掉你的利爪,并且磨平你的牙齿,我就立刻让女儿与你成婚。”
        
        狮子高兴得不得了,说道:“只要能娶到她,什么条件我都答应,我马上按照你的意思去做!”
        
        狮子回去后剪掉了自己尖利的爪子,在磨石上磨平了尖锐的牙齿。他打扮一新,到农夫家里迎娶新娘。可是到了农夫家门口,却发现农夫手提木棒,朝自己走来,看样子来者不善。狮子警惕地摆好了架势。
        
        果然农夫一阵乱棒像雨点一样敲击下来,但是狮子却无力还击,因为他的爪子和牙齿全然没有任何威力。
        
        最后狮子落荒而逃,更糟糕的是,没有了尖牙、利爪,狮子再也无法捕捉到猎物,最后饿得奄奄一息。

    角色类

    package domain;
    
    /**
     * @author Jennyism
     * @date 2020/1/27 0027 21:47
     */
    public abstract class Role {
        private String name;
    
        public void say(String words) {
            System.out.println(getName() + ":" + words);
        }
    
        public void think(String feel) {
            System.out.println(getName() + "觉得" + feel);
        }
    
        public void attack(Role role) {
            System.out.println(getName() + "对" + role.getName() + "发起攻击");
        }
    
        public void doSomething(String some) {
            System.out.println(getName() + some);
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    

    狮子类

    package domain;
    
    /**
     * @author Jennyism
     * @date 2020/1/27 0027 21:52
     */
    public class Lion extends Role {
        private boolean claw;
        private boolean canineTeeth;
    
        public Lion(String roleName) {
            setName(roleName);
            System.out.println("我是一只狮子,我的名字叫" + getName() + ",我爱上了农夫的女儿");
        }
    
        public void wantMarry(Role role) {
            System.out.println(getName() + "想娶" + role.getName());
        }
    
    
    
        public boolean hasClaw() {
            return claw;
        }
    
        public void setClaw(boolean claw) {
            if (!claw){
                System.out.println(getName()+"剪掉了自己尖利的爪子!");
            }
            this.claw = claw;
        }
    
        public boolean hasCanineTeeth() {
            return canineTeeth;
        }
    
        public void setCanineTeeth(boolean canineTeeth) {
            if (!claw){
                System.out.println(getName()+"在磨石上磨平了尖锐的牙齿。");
            }
            this.canineTeeth = canineTeeth;
        }
    }
    
    

    农夫类

    package domain;
    
    /**
     * @author Jennyism
     * @date 2020/1/27 0027 22:01
     */
    public class Farmer extends Role {
        public Farmer(String roleName){
            setName(roleName);
            System.out.println("我是农夫,我的名字叫"+getName()+",狮子要娶我的女儿,可我不敢拒绝。");
            System.out.println("于是我想到了一个办法。");
        }
    }
    
    

    女儿类

    package domain;
    
    /**
     * @author Jennyism
     * @date 2020/1/27 0027 22:06
     */
    public class Daughter extends Role {
        public Daughter(String roleName){
            setName(roleName);
        }
    }
    
    

    故事讲述

    package client;
    
    import domain.Daughter;
    import domain.Farmer;
    import domain.Lion;
    import domain.Role;
    
    /**
     * @author Administrator
     */
    public class MyFirstClient {
    
        public static void main(String[] args) {
            //狮子有自己的方法,需要赋值到Lion类
            Lion lion = new Lion("Lion Steve");
            //女儿没有再添加新的方法,可以直接赋值给Role类
            Role daughter = new Daughter("Daughter Fuck");
            lion.wantMarry(daughter);
            lion.say("农夫,你能把你的女儿嫁给我吗。");
            Role farmer = new Farmer("Farmer Fuck");
            System.out.println("=============第一段结束==========");
            lion.say("农夫,你要怎样才能把女儿嫁给我!");
            farmer.say("我愿意把女儿嫁给你,可是我的女儿害怕你的尖牙和利爪,而且我也担心这些会伤害到她。如果你能剪掉你的利爪,并且磨平你的牙齿,我就立刻让女儿与你成婚。");
            lion.think("高兴极了");
            lion.say("只要能娶到她,什么条件我都答应,我马上按照你的意思去做!");
            System.out.println("=============第二段结束==========");
            lion.setClaw(false);
            lion.setCanineTeeth(false);
            lion.doSomething("打扮一新,前去迎娶新娘");
            farmer.doSomething("提着木棒走来!");
            farmer.attack(lion);
            lion.attack(farmer);
            lion.doSomething("落败逃走,没有了尖牙、利爪,狮子再也无法捕捉到猎物,最后饿得奄奄一息。");
            System.out.println("=============全剧终==========");
        }
    }
    
    
  • 相关阅读:
    WiFi流量劫持—— 浏览任意页面即可中毒!
    POJ3614防晒霜 这个贪心有点东西(贪心+优先队列)
    7月24日训练记录
    环形均分纸牌问题(中位数)
    7月23日训练总结
    7.22学习总结
    POJ 1176 Party Lamps&& USACO 2.2 派对灯(搜索)
    尘埃落定,以梦为马,不负韶华
    P1522 牛的旅行 Cow Tours(floyd)
    分享一种解题的思想,有关时间复杂度探讨
  • 原文地址:https://www.cnblogs.com/Jennyism/p/javase-07.html
Copyright © 2011-2022 走看看