• 面向对象基础总结


    1.对象和类

      1.1 对象和类的关系:对象是类的实例,类是对象的模板。

      1.2 对象:拥有属性和方法

        属性:静态特征,数据,变量

        方法:动态特征,行为,功能

        属性是数据,方法就是对数据的操作

      1.3 面向对象:
        对象:现实世界中的所有实体都是对象(万物皆对象)

         类 : 对具有共同属性和行为的对象进行抽象,得到的一个抽象的概念

        在面向对象编程时要追求低内聚,高耦合(模块越独立越好,模块间的关系越松散越好)

        面向对象编程的特点和好处:面向对象更方便代码的修改,维护,扩展;数据和功能是一个整体

    2.封装

      2.1 什么是封装:
        将类的某些信息隐藏在类内部,不允许外部程序直接访问,通过调用方法来实现对隐藏信息的操作和访向。

        隐藏对象的属性和实现细节,仅对外提供公共访问方式。

        方法:封装操作

        类:数据+对数据的操作

        getter和setter方法:不能直接操作成员变量

      2.2 如何使用封装:

        使用访问修饰符  

      2.2.封装的好处:

        将变化隔离;便于使用;提高重用性;安全性。

      2.3 封装的格式:   

        1、使用访问修饰符修饰成员变量和成员方法
        2、对外提供getter和setter方法

    3.继承
        3.1 什么是继承:

          继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。

       3.2 继承的优缺点:   

          优点 :

          新的实现很容易,因为大部分是继承而来的 
          
    很容易修改和扩展已有的实现 

          缺点 :
          打破了封装,因为基类向子类暴露了实现细节 
          白盒重用,因为基类的内部细节通常对子类是可见的 
          当父类的实现改变时可能要相应的对子类做出改变 
          不能在运行时改变由父类继承来的实现 


          由此可见,组合比继承具有更大的灵活性和更稳定的结构,一般情况下应该优先考虑组合。只 
          有当下列条件满足时才考虑使用继承: 
          子类是一种特殊的类型,而不只是父类的一个角色 
          子类的实例不需要变成另一个类的对象 
          子类扩展,而不是覆盖或者使父类的功能失效

        3.3 继承的格式:

          子类名 extends 父类名{ }

        3.4 继承关系下代码的执行顺序 

          父类的静态代码块
          子类的静态代码块
          父类的构造代码块
          父类的无参构造方法
          子类的构造代码块
          子类的无参构造方法
          =============================
          父类的构造代码块
          父类的无参构造方法
          子类的构造代码块
          子类的有参构造方法
           总结:1、优先调用父类
              2、静态代码优先加载,且只加载一次(作用:第一个对象创建时,执行一些操作(记录日志:))
              3、构造代码块每次调用构造方法时都会调用(作用:每一个该类创建时可以记录日志)
              4、子类的构造方法不管有参无参都会先去调用父类的无参构造

     1 //测试类
     2 public class TestDemo{
     3     public static void main(String[] args) {
     4         Son son =new Son();
     5         System.out.println("=============================");
     6         Son son2 =new Son("name");
     7     }
     8 }
     9 //父类
    10 class Father {
    11     static {
    12         System.out.println("父类的静态代码块");
    13     }
    14     {
    15         System.out.println("父类的构造代码块");
    16     }
    17     public Father() {
    18         System.out.println("父类的无参构造方法");
    19     }
    20     public  Father(String name) {
    21         System.out.println("父类的有参构造方法");
    22     }
    23 
    24 }
    25 //子类
    26 class Son extends  Father {
    27     static {
    28         System.out.println("子类的静态代码块");
    29     }
    30     {
    31         System.out.println("子类的构造代码块");
    32     }
    33     public Son() {
    34         System.out.println("子类的无参构造方法");
    35     }
    36     public Son(String name) {
    37         System.out.println("子类的有参构造方法");
    38     }
    39     
    40 }
    41 //执行结果:
    42 /*父类的静态代码块
    43 子类的静态代码块
    44 父类的构造代码块
    45 父类的无参构造方法
    46 子类的构造代码块
    47 子类的无参构造方法
    48 =============================
    49 父类的构造代码块
    50 父类的无参构造方法
    51 子类的构造代码块
    52 子类的有参构造方法
    53 */

    4.构造方法

      4.1 定义和作用
        在Java中,任何变量在被使用前都必须先设置初值。Java提供的为类的成员变量赋初值的专门方法。(初始化变量

      4.2  常识:子类的所有构造方法都会去访问一次父类的无参构造方法

        问题:为什么子类要去访问父类的构造方法?

        解析:因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的。所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。

        问题:如果父类中没有无参的构造方法该怎么办?

        分析:父类中没有无参构造,那么子类在初始化的时候就会报错。

           解决办法:1、在父类中加一个无参构造方法

              2、通过使用super关键字去显示的调用父类的带参构造方法

              3、子类通过this去调用本类的其它构造方法(比如用子类的有参去调用自己的无参构造方法,但无参构造里一定要有super())

    5.访问修饰符

      5.1 访问修饰符使用范围

        用来修饰成员变量和成员方法,不能用来修饰局部变量

      5.2 访问修饰符权限

                同类   同包    子类    其他包

        private            V  X  X  X

          默认      V  V  X  X

        protected     V  V  V  X

        public      V  V  V  V 

    6.四个关键字   

      6.1 static(静态的)

        使用范围:用来修饰成员变量、成员方法和代码块

        作用 :

          1.想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。

          2.被静态修饰的成员,可以直接被类名所调用。

          3.静态随着类的加载而加载。而且优先于对象存在。

        命名方式:

          属性(成员变量):
              有static修饰:静态成员(静态变量)

             没有static修饰:实例成员(非静态变量)(非静态成员)

          方法(成员方法):          

              有static修饰:静态方法(静态方法)

             没有static修饰:实例方法(非静态方法)(非静态方法)

          代码块({ })  :

              有static修饰:静态代码块

             没有static修饰:非静态代码块(构造代码块)

         总结 :

          a.不管是静态方法还是非静态方法,都需要调用后执行,其执行的次序和在类里声明的次序无关,区别是静态方法是“class.method"方式执行,非静态方法是"object.method"方式执行,即后者需要创建一个对象。
          b.静态成员变量(也称类变量)先于非静态成员变量初始化,静态成员变量在类第一次加载时初始化,所有对象共享一份静态成员变量,非静态成员变量则在对象创建时初始化  

      

      6.2  final(最终的)

        使用范围:修饰类、修饰方法、修饰变量

        作用:1、修饰的类不可被继承

           2、修饰的方法不能被重写

           3、修饰的变量的值不能更改(即为常量,通常变量名全大写)

        作用(详细):

           1、被final修饰的类不能被继承

           2、被final修饰的成员变量

              a. 必须初始化值。

              b. 被fianl修饰的成员变量赋值,有两种方式:1、直接赋值 2、全部在构造方法中赋初值。

              c. 如果修饰的成员变量是基本类型,则表示这个变量的值不能改变。

              d. 如果修饰的成员变量是一个引用类型,则是说这个引用的地址的值不能修改,但是这个引用所指向的对象里面的内容还是可以改变的。

           3、被final修饰的方法不能被重写

              a. 一个类的private方法会隐式的被指定为final方法。

              b. 如果父类中有final修饰的方法,那么子类不能去重写。

      6.3  this和super

           两者定义的区别:

              this代表本类的引用

              super代表父类存储空间的标识(可以理解为父类的引用,可以操作父类的成员)

           两者使用的区别:

              调用成员变量:

                this.成员变量     调用本类的成员变量

                super.成员变量 调用父类的成员变量

              调用构造方法:

                this(...)  调用本类的构造方法
                super(...)    调用父类的构造方法

              调用成员方法:

                this.成员方法     调用本类的成员方法

                super.成员方法  调用父类的成员方法

    7.方法的相互调用

        静态方法是“class.method"方式执行,非静态方法是"object.method"方式执行,即后者需要创建一个对象。

      7.1 同类 :

         静态调用静态

            a.直接调

            b.类名.方法名

            c.对象名.方法名(不建议使用,因为这样不能分辨是静态调静态还是静态调非静态)

         静态调用非静态

            创建调用类的对象,再对象名.方法名

         非静态调用静态

            a.直接调用

            b.类名.方法名

            c.对象名.方法名(不建议使用)

         非静态调用非静态

            a.直接调用

            b.对象名.方法名

      7.2 不同类

         静态调用静态

            类名.方法名

         静态调用非静态

            创建调用类的对象,再对象名.方法名

         非静态调用静态

            类名.方法名

         非静态调用非静态

            对象名.方法名

    8.方法的重载

      同一个类中,方法名相同,参数的数量,类型,顺序不同即为重载(只与参数有关)

    9.方法的重写

      发生在继承关系下,子类对父类允许访问的方法的实现过程进行重新编写, 方法签名相同(即返回值和形参都不能改变。即外壳不变,核心重写)

    细节题:要答全面

    10.局部变量和成员变量的区别

      内存空间:

        局部变量:栈

        成员变量:数据存储在堆中,栈中存储堆空间的地址

      初始值:

        局部变量:没有初始默认值

        成员变量:有初始默认值

      作用域:

        局部变量:声明的有效的代码块范围使用

        成员变量:类中都能使用

    11.类中定义的静态成员变量和非静态成员变量的区别

      静态成员变量    :属于类,无论创建多少对象,内存中只有一个         调用方法:类.静态成员变量

      非静态成员变量:属于对象,每次创建一个对象都会分配独立的存储空间     调用方法:对象.非静态成员变量

    12.列举抽象类和抽象方法的相关语法

      a.抽象方法只有定义,没有实现

      b.抽象方法所在的类必须是抽象类

      c.抽象类中可以不定义抽象方法

      d.子类继承抽象类必须实现抽象类的抽象方法       

     13.多态

       13.1什么是多态

        解释a.同一对象,调用相同的方法,执行不同的操作。

        解释b.同一引用类型,使用不同的实例执行不同的方法。

      13.2多态的优缺点

           优点:
          提高了代码的扩展性,前期定义的代码可以使用后期的内容。
         缺点:
          前期定义的内容不能使用(调用)后期子类的特有内容。

      13.3 多态的应用

        a.使用父类类型作为方法的参数
        b.使用父类类型作为方法的返回值

      13.4 多态的实现步骤   

        1、子类重写父类的方法
        2、程序运行时,子类对象赋给父类(向上转型)(Object obj = new Dog();)
        3、通过父类对象调用方法,执行的是子类的方法

      13.5 多态的表现形式

          向上转型:子类转向父类

          向下转型:父类转向子类

              绑定方法:
              1.如果是非抽象类,则通过父类名 引用名 = new 子类名();然后使用instanceOf关键字来检查左边的对象是否为右边的实例;

                如果是抽象类,则通过抽象类名 引用名 = new 实现类名();

              2.使用instance0关键字来检查左边的对象是否为右边的实例;

                   Father f = new Son();

                    if(f instanceof Son) {

                      ((Son) f).run();//确认左边的对象是右边的实例后则可以调用方法

                    }

        向下转型会遇到的异常:

    在继承关系下著名的异常:java.lang.ClassCastException(类型转换异常)
    
    父类Animal有两个子类Cat和Dog
    
    向下转型
    
    Animal a = new Cat;
    
    强制转换  Cat c2  =(Cat)a;
    
    可以调用猫的方法c2.catchMouse();
    
    但是
    Animal b = new Dog;
    
    强制转换  Cat c3  =(Cat)b;   此时编译是可以通过的  但是运行就会报错,因为狗和猫没有继
    
    承关系

      举例:a.使用父类类型作为方法的参数

     1 //父类Pet
     2 public class Pet {
     3     public void eat() {
     4         System.out.println("动物吃东西");
     5     }
     6 
     7 }
     8 //子类Dog
     9 public class Dog extends Pet {
    10     public void eat() {
    11         System.out.println("狗吃肉");
    12     }
    13 
    14 }
    15 //子类Cat 
    16 public class Cat extends Pet {
    17     public void eat() {
    18         System.out.println("猫吃鱼");
    19     }
    20 
    21 }
    22 //主人
    23 public class Master {
    24     public void feed(Pet pet) {//直接让父类做形参,将子类对象的地址值赋值给父类
    25 //变量,这样调用的就是子类的方法,因为编译器只认地址,地址是子类的就调用子类
    26 //的方法
    27         pet.eat();
    28     }
    29 
    30 }
    31 //测试类
    32 
    33 public class TestDemo {
    34     public static void main(String[] args) {
    35         Master ma = new Master();
    36         ma.feed(new Dog());
    37         ma.feed(new Cat());
    38 
    39     }
    40 }
    41 //执行结果
    42 狗吃肉
    43 猫吃鱼

       举例:b.使用父类类型作为方法的返回值 

    //简单工厂模式 :
        缺点:破坏了开闭原则,但是以后的学习可以通过反射+配置文件重构代码
    /* 结构的组成: 一个抽象产品(父类) 若干个实体产品(子类) 简单工厂:一个静态方法,返回值是父类对象 测试类:调用时,只需要知道父类和工厂,无需关注具体的子类 */ /* 简单工厂: 产品 抽象产品Car 实体产品Benz BMW 工厂 生产产品 缺点:破坏开闭原则,以后可以通过反射+配置文件重构代码 23个经典的设计模式中没有简单工厂 */ //抽象产品Car public class Car { public void run() { } } //实体产品 public class BMW extends Car { public void run() { System.out.println("BMW run"); } } public class Benz extends Car { public void run() { System.out.println("Benz run"); } } //工厂 public class Factory { public static Car createCar(String type) { Car car = null; switch (type) { case "BMW": car = new BMW(); break; case "Benz": car = new Benz(); break; default: break; } return car; } } //测试类 public class TestDemo { public static void main(String[] args) { System.out.println("先生你要买什么"); Scanner sc = new Scanner(System.in); Factory.createCar(sc.next()).run(); } }

     23中设计模式中最简单的单例模式:

           无论引用多少次对象,内存中只分配一个

     1 public class MySingle {
     2     // 无论引用多少次对象,内存中只分配一个对象
     3     static MySingle mySingle;
     4 
     5     private MySingle() {//私有化构造方法
     6 
     7     }
     8 
     9     public static MySingle getSingle() {//要是静态的不然不能调用方法
    10         if (mySingle == null) {
    11             mySingle = new MySingle();
    12         }
    13         return mySingle;    //返回实例对象
    14     }
    15 }
    16 
    17 
    18 public class MySingleTest {
    19 
    20     public static void main(String[] args) {
    21 
    22         System.out.println(MySingle.getSingle());
    23     }
    24 
    25 }

         
        

        

  • 相关阅读:
    图的应用详解-数据结构
    图的遍历
    node.js基础模块http、网页分析工具cherrio实现爬虫
    NodeJS制作爬虫全过程
    Nodejs爬虫进阶教程之异步并发控制
    asp.net的临时文件夹
    Cms WebSite 编译非常慢
    查看数据库的表被谁锁住了,以及如何解锁
    WinRar 设置默认的压缩格式为zip
    Can not Stop-Computer in powershell 6.0
  • 原文地址:https://www.cnblogs.com/19322li/p/10630859.html
Copyright © 2020-2023  润新知