zoukankan      html  css  js  c++  java
  • 面向对象

    6.面向对象-基础

      1、面向对象编程:OOP(Object-Oriented Programming,OOP)

      2、以类的方式组织代码,以对象的组织(封装)数据

      3、抽象

      4、三大特性:继承、封装、多态

      5、对象是具体的事务;类是抽象的(对对象的抽象);类是对象的模板

    6.1类与对象的关系

    类(现实对象的模板)是一种抽象的数据类型,对某一类事务整体描述/定义;但是不能代表一个具体的事务

      ·动物、植物、家电、、、、

      ·Person类、Pet类、Car类

      ·在一组相同或者类似的对象中,抽取出共性的特征和行为,保留所关注的部分

    对象是抽象概念的具体实例

      ·张三是一个人的的具体实例

      ·能够体现出特点,展现出功能的具体实例,而不是抽象概念

      ·将对象保存在相同类型的实例名(对象名/引用名)变量中

    ·访问属性

     *   对象名.属性名 = 值; //赋值
     * 对象名.属性名 //取值
     调用方法:
     * 对象名.方法名();

     

    6.2创建于初始化对象

      1、使用new关键字创建。分配内存空间+默认初始化+对类中构造器的调用

      2、构造器也成为构造方法,创建对象时必须调用;其特点:必须和类名相同;必须没有返回类型,也不能写void

     package com.oop.object;
     ​
     //学生类
     public class Student {
     ​
         //属性:字段
         String name;
         boolean sex;//1:boy 2:girl
         int age;
     ​
         //方法
         public void study(){
             System.out.println(this.name+"在学习");
        }
     }
     ​
     /**
      * public class Application {
      *     public static void main(String[] args) {
      *         //类是抽象的 需要实例化
      *         Student student = new Student();
      *         student.name = "Joey";
      *         student.sex=true;
      *         student.age=12;
      *         student.study();
      *     }
      * }
      * */

    6.3构造器详解

      1、即使什么方法都不写,也存在一个默认的无参构造器;

      2、无参构造器可以实例化对象(值初始化)

      3、使用new关键字,本质实在调用构造器。

     package com.oop.object;
     ​
     public class Person {
         String name;
         //快捷键:alt+insert ==》生成构造器
         //显示定义(无参)构造器
         public Person(){
     //       this.name = "Joey";
        }
     ​
         //有参构造器 : 一旦定义了有参构造,无参构造必须显示定义
         public Person(String name){
             this.name = name;
        }
     }

    6.4小结

    1、类与对象;类是一个模板:抽象,对象是一个具体的实例

    2、方法:定义&调用(避免方法死循环)

    3、对象的引用:

      引用类型: 基本类型(8种)

      对象是通过引用来操作的:栈 ---》 堆

    4、属性 :字段Field成员变量

    默认初始化:

    数字:0 0.0

    charu0000

    booleanfalse

    引用:null

      修饰符 属性类型 属性名 = 属性值

    5、对象的创建和使用

      -必须使用new关键字来创建(默认的无参构造器,自定义有参构造器(必须显示定义无参构造器))  

          Person p = new Person();

      -对象的属性 : p.name

      -对象的方法: p.hello()

    6、类

      静态的属性 属性

      动态的行为 方法

    7、局部变量(要求先赋值再使用,否则报未初始化错误)与实例变量区别

    变量的属性局部变量成员变量(实例)
    定义位置 方法或者方法内部结构当中 类的内部,方法的外部
    默认值 字面值(与数组相同)
    使用范围 从定义行、列到包含其结构结束 本类有效
    命名冲突 不允许重名 可与局部变量重名(局部变量优先)

     

    7.面向对象-三大特性

    7.1封装

      封装:数据的隐藏

      程序设计追求“高内聚,低耦合”

      私有属性:get/set

    封装的意义:  

      1、提高了程序的安全性

      2、隐藏代码的实现细节

      3、统一接口

      4、系统可维护性增强

     package com.oop.encapsulation;
     ​
     public class Student {
         //姓名
         private String name;
         //学号
         private int ID;
         //年龄
         private int age;
         //性别 1:boy 2:girl
         private boolean sex;
         //专业
         private String major;
     ​
         public String getName() {
             return name;
        }
     ​
         public void setName(String name) {
             this.name = name;
        }
     ​
         public int getID() {
             return ID;
        }
     ​
         public void setID(int ID) {
             this.ID = ID;
        }
     ​
         public int getAge() {
             return age;
        }
     ​
         public void setAge(int age) {
             this.age = age;
        }
     ​
         public boolean isSex() {
             return sex;
        }
     ​
         public void setSex(boolean sex) {
             this.sex = sex;
        }
     ​
         public String getMajor() {
             return major;
        }
     ​
         public void setMajor(String major) {
             this.major = major;
        }
     }

    7.2继承

      Java中所有的类都默认直接或者间接继承Object类

      继承的本质是对某一批类的抽象

      extends是“扩展”;即子类是父类的扩展(子类会拥有父类的全部公共(public)方法)

      Java中只有单继承没有多继承(一个儿子可以有一个爸爸,一个爸爸可以有多个儿子)

      继承是类与类之间的关系,除了继承以外还有依赖、组合、聚合  

      继承关系的两个类,一个为子类(派生类),一个为父类(基类)

      Object类、super、方法重写

    7.2.1 super详解

    super注意点:

      1、super调用父类的构造方法,必须处于代码(构造方法)中的第一行

      2、super必须只能出现在子类的方法或者构造方法中

      3、super和this不能同时调用构造方法

    VS this:

    代表的对象不同:

      this:本身调用本类的对象

      super:代表父类对象的应用

    前提:

      this:没有继承也可以使用

      super:只能在继承条件下才能使用

    构造方法:

      this():本类的构造

      super():父类的构造

    Person(父类)

     package com.oop.inherit;
     ​
     public class Person {
         //父类无参构造
         public Person(){
             System.out.println("父类无参构造");
        }
         //父类有参构造
         public Person(String name){
             System.out.println("父类有参构造");
        }
         //人的特性
         public void say(){
             System.out.println("Say Hello!!!");
        }
     ​
         protected String name = "Joey";
     ​
         public void print(){
             System.out.println("Person");
        }
     }

    Student(子类)

     package com.oop.inherit;
     ​
     public class Student extends Person{
         public Student(){
             super();
             System.out.println("子类无参构造");
        }
         public Student(String name){
             System.out.println("子类有参构造");
        }
     ​
         private String name = "Rose";
     ​
         public void test(String name){
             System.out.println(name);//main中的参数名
             System.out.println(this.name);//Student类本类中的名字
             System.out.println(super.name);//父类中的名字
        }
     ​
         public void print(){
             System.out.println("Student");
        }
     ​
         public void test1(){
             print(); //当前类对象
             this.print(); //当前类对象
             super.print(); //父类对象
        }
     }
     /*
     * public class Application {
         public static void main(String[] args) {
             Student s = new Student();
             s.test("乔伊");
             s.test1();
         }
     }
     * */
     ​

    7.2.2方法重写

      重写是方法的重写;与属性无关

    重写注意点:

      1、需要有继承关系;子类重写父类的方法

      2、方法名必须相同

      3、参数列表也必须相同

      4、修饰符:范围可以扩大,但是不能缩小 public>protected>Default>private

      5、抛出的异常:范围可以被缩小,但是不能扩大:ClassNotFoundException --->Exception(大)

      6、子类和父类方法必须一致;方法体不同

    为什么需要重写?

      1、父类的功能子类不一定需要

      2、Alt+Insert 选中Override(重写)

    不能被重写的情况:  

      1、static 方法属于类,不属于实例

      2、final 常量 不能被重写

      3、private 方法不能被重写

    B类(父类)

     package com.oop.inherit;
     ​
     public class B {
         public static void test(){
             System.out.println("B=>test()");
        }
     ​
         public void test1(){
             System.out.println("B=>test1()");
        }
     }
     ​

    A类(子类)

     package com.oop.inherit;
     ​
     public class A extends B{
         public static void test(){
             System.out.println("A=>test()");
        }
     ​
         @Override  //注解:有功能的注释
         public void test1() {
     //       super.test1();
             System.out.println("重写B的test1");
        }
     }
     ​
     /*
     * public static void main(String[] args) {
             B b = new A();
             b.test1();
     ​
         }
     * */

    7.3多态

      同一方法根据发送对象的不同而采用不同的行为方式

      动态编译:类型;可扩展性变强;屏蔽子类间的差异;灵活,耦合度低

    多态存在的条件:

    有继承关系

      子类重写父类的方法

      父类引用指向子类对象

      多态是方法的多态,属性没有多态性

    多态的注意点:

      1、多态是方法的多态,属性没有多态

      2、父类和子类有联系,否则会有类型转换异常:ClassCastException

      3、存在的条件: 继承关系;方法需要重写;父类引用指向子类对象

      4、子类转为父类:向上转型

      5、父类转为子类:向下转型(需要强制转换)

      6、方便方法的调用,减少重复的代码!简介

     package com.oop.polymorphic;
     //父类
     public class Father {
         public void run(){
             System.out.println("Dad running!");
        }
     }
     ​
     package com.oop.polymorphic;
     ​
     public class Son extends Father{
         @Override
         public void run() {
             System.out.println("Son running!");
        }
     ​
         public void eat(){
             System.out.println("eating!");
        }
     }
     /*
     *   public static void main(String[] args) {
             Son s = new Son();
             Father f = new Son(); //父类的引用指向子类的对象
             Object o = new Son();
             
             s.run();
             f.run(); //子类重写父类方法,执行子类的方法
     ​
             //对象能够执行哪些方法,主要看对象左边的类型
             s.eat();
             ((Son) f).eat(); //强制转换f为Son类型
         }*/

    7.3.1 instanceOf 类型(引用)转换

     public class Application {
        //instanceof 判断是否存在父子关系 是返回true 否则false
         public static void main(String[] args) {
             //Object > Father > Son
             //Object > String
             Object o = new Son();
     ​
             System.out.println(o instanceof Son);
             System.out.println(o instanceof Father);
             System.out.println(o instanceof Object);
             System.out.println(o instanceof String);
        }
     }
     /*
     *   public static void main(String[] args) {
             Son s = new Son();
             Father f = new Son(); //父类的引用指向子类的类型
             Object o = new Son();
     ​
             s.run();
             f.run(); //子类重写父类方法,执行子类的方法
     ​
             //对象能够执行哪些方法,主要看对象左边的类型
             s.eat();
             ((Son) f).eat(); //强制转换f为Son类型
         }*/

    7.3.2多态的应用

      场景一:使用父类作为方法形参实现多态,使方法的参数类型更为宽泛

      场景二:使用父类作为方法返回值实现多态,使方法可以返回不同的子类对象

    7.3.3装箱

      向上转换:父类引用中保存真实的子类对象,称为向上转型(多态核心)

                      Animal a = new Dog();

    7.3.4插箱

      向下转型(拆箱):将父类引用中的真实子类对象,强行转换为子类本身类型,向下转型。

                      Dog dog = (Dog)a;

      向下转型之前,应该判断引用中的真实子类对象类型,保证类型转换的正确性

     

    8.面向对象-补充

    8.1抽象类(abstract)

      可以修饰方法(抽象方法)也可以修饰类(抽象类)

      抽象类中可以没有抽象方法;但是有抽象方法的类一定要声明为抽象类

      抽象类,不能使用new关键字来创建对象,用来让子类继承

      抽象方法:只有方法的声明,没有方法的实现,用来让子类实现的

      子类继承抽象类,必须实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类

     package com.oop.others;
     ​
     //该类为抽象类
     public abstract class Action {
     ​
         //抽象方法 只有方法的约束 没有方法体
         public abstract void doSomething();
         /*
         * 1、不能new抽象类,只能靠子类取实现它:约束
         * 2、抽象类中可以写普通的方法
         * 3、抽象方法必须在抽象类中
         * */
     }
     ​
     package com.oop.others;
     ​
     //abstract 抽象类; 类 extends:单继承(接口可以实现多继承)
     //子类继承抽象类,必须实现抽象类中所有的方法;除非子类也是一个抽象类
     public class A extends Action{
         public void doSomething() {
             System.out.println("继承抽象类A ");
        }
     }

    8.2接口

    interface

      普通类:只有具体实现

      抽象类:具体实现和规范(抽象方法)都有

    接口:只有规范!自己无法写方法;约束和实现分离

      接口就是规范(定义的一组规则;本质==契约;面向对象(OO)的精髓)

    作用

      1、约束(定义一些规则)

      2、定义一些方法,让不同的人实现

      3、默认方法:public abstract

      4、默认常量:public static final

      5、接口不能被实例化;接口中没有构造方法

      6、implements可以实现多个接口

      7、必须要重写接口中的所有的方法

                                  与抽象类的异同:

    相同点不同点
    可编译字节码文件 所有属性都是公开静态常量,隐式使用public static final修饰
    不能创建对象 所有方法都是公开抽象方法,隐式使用public abstract修饰
    可以作为引用对象 没有构造方法和静态代码块
    具备Object类中的所有定义的方法  

    接口引用:

      类与类:单继承;extends 父类名称

      类与接口:多实现;implements 接口名称1,接口名称2,,,接口名称n

      接口与接口:多继承;extends 父接口1,2,3,,,,n

     package com.oop.others;
     ​
     //interface 接口的关键字
     //接口都需要实现类
     public interface UserService {
     ​
        //常量 默认:public static final
        public static final boolean sex = true;
        int age = 21;
     ​
        /*方法默认为 public abstract ;接口中所有的定义都是抽象的*/
        void run();
        void eat(String name);
     }
     ​

     

     package com.oop.others;
     ​
     public interface TimeService {
         void checkTime();
     }
     ​
     package com.oop.others;
     ​
     //抽象类:extends~
     //类 可以实现接口 implements 接口
     //重写接口里面的所有方法
     public class UserServiceImpl implements UserService,TimeService{  //多继承(利用接口)
     ​
         public void run() {
             System.out.println("running");
        }
     ​
         public void eat(String name) {
             System.out.println(name+"eating");
        }
     ​
         public void checkTime() {
             System.out.println("现在是北京时间:");
        }
     }

    8.3内部类

    特点:

      -编译后可以独立的生成字节码文件

      -内部类可以直接访问外部类的私有成员,而不破坏封装

      -可以为外部类定义必要的组件

    一个类的内部在定义一个类

    1、成员内部类

      -类的内部定义,与实例变量和实例方法同级别的类

      -外部类的一个实例部分,创建对象时,必须依赖外部类对象

      -当外部类和内部类存在重名属性,优先访问内部类属性

      -成员内部类不能定义静态成员

    2、静态内部类

      -不依赖外部类对象,可直接创建或者通过类名访问,可声明静态成员

      -只能访问外部类的静态成员(实例成员需要实例化外部类对象)

    3、局部内部类

      -定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

      -局部内部类访问当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final

      -限制类的使用范围

    4、匿名内部类

      -没有类名的局部内部类(其余特征与局部内部类相同)

      -必须继承一个父类或者实现一个接口

     package com.oop.inner;
     ​
     public class Outer {
     ​
         protected String sex;
         private int id = 10;
         public String name;
         public void out(){
             System.out.println("外部类方法输出");
        }
         public class Inner{
             public void in(){
                 System.out.println("这是内部类的输出");
            }
             //获得私有属性
             public void getId(){
                 System.out.println(id);
            }
        }
     }
     /*
     * public static void main(String[] args) {
             Outer outer = new Outer();
             //通过外部类实例化内部类
             Outer.Inner inner = outer.new Inner();
             inner.getId();
         }
     * */

     

  • 相关阅读:
    IDEA2019.1.2破解教程
    Java基础 -- 常见异常
    Java基础 -- Java基本类(部分)
    Java基础 -- IO流
    Java基础 -- Java方法
    Java数组
    IDEA首次配置问题
    Java开发环境搭建
    dos的几种打开方式和基本dos命令
    SpringBoot内外部配置文件加载和优先级
  • 原文地址:https://www.cnblogs.com/joey-413/p/13234845.html
Copyright © 2011-2022 走看看