专栏首页阿Q说代码面向对象:封装?继承?多态?

面向对象:封装?继承?多态?

今天我们来了解一下面向对象的三大特性:封装、继承和多态。

封装

把属性和实现细节隐藏起来,不让外界直接访问,提供公共的方法访问方式。

private:

A:只能修饰成员

B:被private修饰的成员只能在本类中访问,外界不可以直接访问

C:private是一个权限修饰符

使用:

1)给成员属性加private

2)提供关于这个属性的公共的set和get方法

        class Demo_Person {
                public static void main(String[] args) {
                    Person p1 = new Person();
                    p1.name = "张三";//调用姓名属性并赋值
                    //p1.age = -17;    //因为age是私有的所以 不能直接调用赋值
                    //p1.speak();       //调用行为

                    p1.setAge(-17);

                    System.out.println(p1.getAge());
                }
            }
            
            //人的类
            class Person {
                String name;                //姓名
                private int age;            //年龄

                public void setAge(int a) {    //设置年龄
                    age = a;    
                }

                public int getAge() {           //获取年龄
                    return age;
                }

                public void speak() {
                    //这里可以直接使用age是因为是在Person类里面
                    System.out.println(name + "..." + age);
                }
            }
this:

指的是当前对象的引用

用途:用来区分成员变量和局部变量重名

    class Demo1_This {
        public static void main(String[] args) {
            Person p1 = new Person();
            p1.setName("张三");
            p1.setAge(23);
            System.out.println(p1.getName() + "..." + p1.getAge());

            Person p2 = new Person();
            p2.setName("李四");
            p2.setAge(24);
            System.out.println(p2.getName() + "..." + p2.getAge());
        }
    }

    class Person {
        private String name;            //姓名
        private int age;            //年龄
                
        public void setAge(int age) {       //设置年龄
            this.age = age;
        }

        public int getAge() {           //获取年龄
            return age;
        }

        public void setName(String name) {  //设置姓名
            this.name = name;
        }

        public String getName() {       //获取姓名
            return name;
        }
    }

构造方法

构造方法是为了创建对象而存在的,一个对象的创建肯定会执行构造方法。一般在构造方法中做初始化操作。构造方法的的特点:没有返回值,连void都不能有;方法名和类名一模一样;方法里面没有返回值(但是可以写一个单独的 return;)

构造方法的重载

构造方法可以重载(只要符合重载的条件就可以:方法名相同,参数列表不同)

代码:

    class Person {
        private String name;
        private int age;
        //构造方法
        public Person() {
        }
        public Person(String name,int age) {
            this.name = name;
            this.age = age;
        }
    }
注意事项

A:如果我们在一个类中没有给出构造方法, 系统将默认给出一个无参构造

B:如果我们给出了构造方法, 系统将不再提供无参构造(所以我们以后在定义类的时候,永远手动给出无参构造)

有参构造和Set方法的区别

有参构造方法,是在创建对象的同时顺便给成员变量进行赋值 ,强调的是创建对象 而set方法 就是为了给成员变量赋值的一个方法

一个对象的创建步骤
  1. 首先想要创建某个类的对象,必须先把类的class文件加载到方法区
  2. 写一个引用
  3. 遇到new就去堆内存中开辟空间
  4. 默认初始化
  5. 显示初始化(如果有显示初始化就进行)
  6. 执行构造方法, 如果构造方法里面有赋值操作,就进行赋值
  7. 把地址值赋值给引用

static静态

特点:

  1. 随着类的加载而加载,随着类的消失而消失,因为静态的会一直存在静态区中,直到虚拟机停止,而堆内存中的内容只要没有指向的时候,过一段时间就会被回收,所以不要把任何东西都定义成静态的
  2. 优先于对象而存在
  3. 被包含静态的这个类的所有对象共享
  4. 不仅能用对象名调用,还能用类名直接调用(推荐类名调用,因为既然能用类名调用 ,又何必浪费个内存创建个对象来调用呢)

代码:

    class Person {
        String name;                //姓名
        static String country;          //国籍

        public void speak() {           //说话的方法
            System.out.println(name + "..." + country);
        }
    }
    class Demo1_Static {
        public static void main(String[] args) {
            Person p1 = new Person();   
            p1.name = "苍老师";            
            p1.country = "日本";      
                
            Person p2 = new Person();
            p2.name = "小泽老师";   
                
            p1.speak();    //打印出 苍老师...日本
            p2.speak();    //打印出 小泽老师...日本

            Person.country = "日本";  //静态多了一种调用方式,可以通过类名.
            System.out.println(Person.country);
        }
    }
注意事项

1:静态方法里面不能有this关键字(原因是因为静态是随着类的加载而加载,this是随着对象的创建而存在。静态比对象先存在)

2:非静态的能访问静态的;静态的不能直接访问非静态的;如果静态的非得访问非静态的内容,请创建对象使用非静态的内容。

代码体现:

    class Demo {
        int num1 = 10;  //非静态的成员变量
        static int num2 = 20;   //静态的成员变量

        public void print1() {  //非静态的成员方法,既可以访问静态的成员也可以访问非静态的
            System.out.println(num1);
            System.out.println(num2);
        }

        public static void print2() {   //静态的成员方法
            //System.out.println(num1);//静态的成员方法不能访问非静态的,错误: 无法从静态上下文中引用非静态 变量 num1
                
            Demo d = new Demo();        //如果静态的非要访问非静态的内容 请创建对象使用
            System.out.println(d.num1);
            System.out.println(num2);
        }
    }
静态变量、成员变量、局部变量的区别
  1. 书写位置静态 :类中方法外,加了一个关键字 static成员: 类中方法外,没有static局部: 方法内
  2. 内存静态:方法区里面的静态区成员:堆局部:栈
  3. 生命周期静态:随着类的加载而加载,随着类的消失而消失(虚拟机停掉才会消失)成员:随着对象的创建而存在,随着对象消失而消失(当一个对象没有任何指向的时候,过一段时间垃圾回收器就会来清理)局部:随着方法的调用而存在,随着方法的执行完毕而消失
  4. 初始化:静态:有默认初始化成员:有默认初始化局部:没有默认初始化,所以在使用之前必须先赋值
  5. 调用不同:静态:类名可以调用,对象名也可以调用成员:只能对象名调用局部:只能在方法内部直接使用 无需在前面加限定

代码块

在java中用{}括起来的称为代码块。

  1. 局部代码块,在方法内部{},限定变量生命周期,及早释放,提高内存利用率
  2. 构造代码块,在方法外面,类里面{},每创建一次对象就执行一次,而且是在构造方法执行前执行的,所以说就可以把构造方法里面的共性内容写到构造代码块里面。为什么说构造代码块是在构造方法前面执行呢?一个对象的初始化是先默认初始化,接着显示初始化,最后执行构造方法,这样一个对象就创建完毕了。构造代码块就在显示初始化阶段执行的。
  3. 静态代码块在方法外面,类里面static{},随着类的加载而执行,只执行一次,做一些全局初始化的内容。

例子:

    class Student {
        static {
            System.out.println("Student 静态代码块");
        }
        
        {
            System.out.println("Student 构造代码块");
        }
        
        public Student() {
            System.out.println("Student 构造方法");
        }
    }

    class Demo_Student {
        static {
            System.out.println("Demo_Student静态代码块");
        }
        
        public static void main(String[] args) {
            System.out.println("我是main方法");
            Student s1 = new Student();
            Student s2 = new Student();
        }
    }
    执行结果:
        Demo2_Student静态代码块
        我是main方法
        Student 静态代码块
        Student 构造代码块
        Student 构造方法
        Student 构造代码块
        Student 构造方法

继承

继承就是子类继承父类的特征和行为。extends:是个关键字,表示子类继承父类。被继承的类叫做父类或基类或超类,继承的类叫做子类或者派生类。

  • 继承的好处是提高了代码的复用性和可维护性 复用性:就是子类直接使用父类的内容,不用再把父类的代码在子类中写一边了, 维护性:假如我想修改所有子类的中同样的方法,我只需要修改父类中的方法,子类中的就都被修改了
  • 继承的弊端是耦合性太强

耦合性:假如我只想修改父类中的方法,但是又不想修改子类中的方法,可是我只要修改了父类中的内容,子类继承父类 子类中的内容也就被一起修改了。

  • 开发原则:高内聚,低耦合 耦合:类与类的关系 内聚:就是自己完成某件事情的能力 比如:某件是封装成一个方法就能完成,可你非要封装成两个方法 这就不是高内聚

java只支持单继承不支持多继承,但是可以多层继承。如果想用这个体系的所有功能用最底层的类创建对象,如果想看这个体系的共性功能,看最顶层的类 。代码如下:

class Demo_Extends {
    public static void main(String[] args) {
        DemoC d = new DemoC();
        d.show();
        d.method();
        d.print();
    }
}
class DemoA {
    public void show() {
        System.out.println("DemoA");
    }
}

class DemoB extends DemoA {
    public void method() {
        System.out.println("DemoB");
    }
}

class DemoC extends DemoB {
    public void print() {
        System.out.println("DemoC");
    }
}
  • 继承的注意事项 private修饰的不能被继承;构造方法不能被继承,但是可以通过super来访问父类的构造方法什么时候使用继承呢? 只有 "谁是谁的一种"的时候才去考虑继承
  • 继承中的成员变量 变量的使用遵循就近原则, 当方法内使用一个变量,首先看局部位置有没有,如果没有就去成员位置找;如果成员位置没有,就去看父类。
  • this和super的区别this代表当前对象的引用 ,不仅可以调用本类的,也可以调用父类的(本类没有的前提下才能调用父类的)super代表的是父类内存空间的标识,构造方法中this()和super()不能共存。
  • 继承中的构造方法子类所有的构造方法第一行都默认去访问父类中的空参构造方法,因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。
  • 继承中的成员方法方法的重写:在子父类关系中,子类出现和父类一模一样的方法,就叫做方法的重写。重写的注意事项:A:父类私有的不能被重写 B:子类重写父类的方法,权限必须大于等于父类的权限C:静态的方法只能被静态方法重写(静态只能覆盖静态,其实不算重写,多态时候详细讲解)
  • 重载和重写的区别重写:发生在子父类中,子类出现和父类一模一样的方法,才是方法的重写 重载:发生在一个类中,只要满足方法名相同,参数列表(顺序 个数 类型)不同,与返回值无关的方法。

多态

多态是同一个行为具有多个不同表现形式或形态的能力。

  • 多态的前提有继承或者实现关系有方法的重写有父类的引用指向子类的对象 class Demo1_Polymorphic { public static void main(String[] args) { Cat c = new Cat(); c.eat(); Animal a = new Cat();//父类引用指向子类对象 a.eat(); } } class Animal { public void eat() { System.out.println("动物吃饭"); } } class Cat extends Animal { public void eat() { System.out.println("猫吃鱼"); } }
  • 多态的成员使用特点

成员变量:编译看左边,运行看左边 成员方法:编译看左边,运行看右边 静态方法:编译看左边,运行看左边(静态和类相关,算不上重写,所以,访问还是左边的) 在多态的时候,父类的引用除了子类重写的方法是调用的子类的之外, 其他的都是调用的父类自己的,如果父类没有,编译就报错。

  • 多态的好处和弊端好处:提到代码的扩展性和维护性坏处:不能使用子类特有的方法和属性
  • 向上转型和向下转型Person p = new SuperMan();向上转型SuperMan sm = (SuperMan)p;向下转型 在多态中,父类的引用不能使用子类特有的功能和属性,如果想使用必须向下转型。
    class Demo3_SuperMan {
        public static void main(String[] args) {
            Person p = new SuperMan();//父类引用指向子类对象,超人提升为了人
            //父类引用指向子类对象就是向上转型
            System.out.println(p.name);
            p.谈生意();
            SuperMan sm = (SuperMan)p;//向下转型
            sm.fly();//只有父类的引用强转成子类后,才能使用子类特有的功能
        }
    }
    class Person {
        String name = "John";
        public void 谈生意() {
            System.out.println("谈生意");
        }
    }
    class SuperMan extends Person {
        String name = "superMan";

        public void 谈生意() {
            System.out.println("谈几个亿的大单子");
        }

        public void fly() {
            System.out.println("飞出去救人");
        }
    }

阿Q用了两天的时间把这块做了简单总结,如果有什么不懂得地方可以给阿Q留言今。想了解更多学习知识,请关注微信公众号“阿Q说”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

本文分享自微信公众号 - 阿Q说代码(AQ_Shuo),作者:阿Q

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 面向对象封装、继承、多态

    身份运算符用于 比较 两个对象的 内存地址 是否一致 —— 是否是对同一个对象的引用

    py3study
  • 一文理清面向对象(封装、继承、多态)+ 实战案例

    面向过程其实就是把过程当做设计核心,根据问题的发展顺序,依次解决问题,尽可能的把过程中涉及到的问题完善解决。他有他的优点,当拿到一个问题时,可以方便的按执行的步...

    程序IT圈
  • JavaScript 面向对象(封装、继承、多态)多种方式实现完全总结

    封装就是把抽象出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。 创建对象实现封装可...

    csxiaoyao
  • Java面向对象基础(封装继承多态)【2】

    需要让用户知道的才暴露出来,不需要让用户知道的全部隐藏起来,这就是封装。说的专业一点,封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内...

    Weaster
  • Java面向对象基础(封装继承多态)【1】

    面向对象的三大特征:继承、封装、多态进行详细的讲解。另外还包括抽象类、接口、内部类等概念。很多概念对于初学者来说,更多的是先进行语法性质的了解,然后进行大量的练...

    Weaster
  • Java面向对象基础(封装继承多态)【3】

    使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。

    Weaster
  • 到底啥是面向对象?啥是封装、继承、多态?

    面向对象呢也有一个高大上的名字叫OOP,是现在最流行的编程思想,正所谓万物皆对象,当然不是那个对象(你懂得)。在日常生活中,一辆挖掘机是对象,一辆...

    Python进击者
  • Java面向对象基础(封装继承多态)【4】 异常处理

    在实际工作中,我们遇到的情况不可能是非常完美的。比如:你写的某个模块,用户输入不一定符合你的要求;你的程序要打开某个文件,这个文件可能不存在或者文件格式不对;你...

    Weaster
  • PHP 面向对象篇:继承、封装与多态

    上篇教程学院君给大家介绍了 PHP 面向对象编程中的基本概念 —— 类与对象,今天我们在此基础上来看看面向对象的三大特性:继承、封装与多态。

    学院君
  • 面向对象三大特性-----封装、继承、多态

      前面有文章写到了面向对象编程和面向对象设计的头五大原则(SOLID五大原则)。今天我们再来谈谈面向对象的三大特性--封装、继承、多态

    小世界的野孩子
  • 面向对象三要素:封装继承多态的阐述及示例

      面向对象的三个基本特征是:封装、继承、多态。 一 封装   封装就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员。隐藏了类的实...

    深度学习思考者
  • java学习笔记(基础篇)—面向对象编程之封装、继承、多态

    Java的编程语言是面向对象的,采用这种语言进行编程称为面向对象编程(Object-Oriented Programming, OOP), 它允许设计者将面向对...

    chlinlearn
  • 「JAVA」面向对象三大特征:封装、继承、多态,以高内聚、低耦合为目标

    面向对象的最终目的是要构建强健、安全、高效的项目,也就是要实现项目的高内聚和低耦合:

    老夫编程说
  • 面向对象的三大特性(封装、继承、多态)

    继承 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类...

    用户1214487
  • 面向对象语言的三大特征: 封装 继承 多态(二)——继承

    子类去重写父类中的方法, 当子类重写了父类中的方法,子类再调用该方法时 调用的是子类重写之后的

    诡途
  • 【python】面向对象的三大特征(封装、继承、多态)

    同一个函数在多个类中都有(可能实现方法各有不同),最后哪个类作为传入对象,就调用谁家的该函数。

    JNingWei
  • 面向对象语言的三大特征: 封装 继承 多态(一)——封装

    简单来说: 将某些部分隐藏起来(私有化),程序的其他位置是看不到的(没有办法直接调用)

    诡途
  • Java 面向对象编程三大特性: 封装 继承 多态

    封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方...

    赵哥窟
  • 面向对象:封装,多态

    1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如....

    changxin7

扫码关注云+社区

领取腾讯云代金券