java基础知识总结(二)

2021-06-09 15:05

阅读:481

标签:一个   基类   run   特征   name   虚拟   兔子   throws   类的成员   

1. 面向对象

1.1 多态

多态同一个行为具有多个不同表现形式或形态的能力。是指一个类实例(对象)的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

其实就是运用了重写和重载的机制

分为重载多态和重写多态
重载式多态: 也叫编译时多态。也就是说这种多态再编译时已经确定好了。重载大家都知道,方法名相同而参数列表不同的一组方法就是重载。在调用这种重载的方法时,通过传入不同的参数最后得到不同的结果。

重写式多态,也叫运行时多态。这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。

在父类写一个虚方法或抽象方法,子类去重写父类的方法,在调用的时候系统会根据对象运行时的类型决定调用哪个方法。
向上转型和向下转型:
向上转型:只能调用父类定义的方法
向下转型,可以调用子类扩展的方法,先向上转型

class Person{
  public void print()
    {
    System.out.println("我是人");
    }
  }
}
class Student extends Person{
  public void print(){
    System.out.println("我是学生");
  }
}
//使用
//向上转型 父类 父类对象 = 子类实例
Person per = new Student();

if(per instanceof Student){
  Student stu = (Student)per;
  stu.fun();
}

1.2 封装

封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员。
 面向对象的不就是使用程序处理事情时以对象为中心去分析吗,与面向过程不同,面向过程关心处理的逻辑、流程等问题,而不关心事件主体。而面向对象即面向主体,所以我们在解决问题时应该先进行对象的封装(对象是封装类的实例,比如张三是人,人是一个封装类,张三只是对象中的一个实例、一个对象)。比如我们日常生活中的小兔子、小绵羊都可以封装为一个类。

主要行为有:
1)将属性私有化,并提供对外界的接口(get/set方法)。
2)用private修饰的属性和方法,只能在本类中使用。

1.3 继承

作用:提高代码的复用性,减少重复代码
思想: 抽象层次化

  1. 子类可以继承父类非私有的属性和方法,不能继承构造方法和私有的属性和方法。
  2. 可以综合子类的共同特征来去提炼父亲的类。
  3. 子类在继承父类的各种属性和方法时,也可以有自己的属性和方法
  4. 一个子类只能有一个父类,java只能单继承,不能多继承,因为多个类中的方法名相同,方法体不同,不知使用哪个
  5. 一个类继承最顶端叫做基类或者超类,所有的超类叫做object
  6. 在继承关系中,如果父类没有无参数的构造方法,如何解决?
    a.子类中添加一个和父类构造方法参数列表相同的构造方法,通过super参数传递给父类的构造方法
    b.如果父类允许修改的时候,可以在父类中创建一个无参的构造方法

2. 七大基本原则

单一职责原则(SRP)

一个类应该有且只有一个去改变它的理由,这意味着一个类应该只有一项工作。

比如在职员类里,将工程师、销售人员、销售经理这些情况都放在职员类里考虑,其结果将会非常混乱,在这个假设下,职员类里的每个方法都要if else判断是哪种情况,从类结构上来说将会十分臃肿。

开放封闭原则(OCP)

对象或实体应该对扩展开放,对修改封闭。

更改封闭即是在我们对模块进行扩展时,勿需对源有程序代码和DLL进行修改或重新编译文件!这个原则对我们在设计类的时候很有帮助,坚持这个原则就必须尽量考虑接口封装,抽象机制和多态技术!

里氏替换原则(LSP)

子类可以扩展父类的功能,但不能改变原有父类的功能

依赖倒置原则(DIP)

高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。具体实现应该依赖于抽象,而不是抽象依赖于实现。

接口隔离原则(ISP)

将不同的功能定义在不同的接口来实现接口的隔离, 避免了其他类在依赖该接口时依赖其不需要的接口, 可以减少依赖的冗余性和复杂性

合成/聚合复用原则

通过在一个新的对象中引入已有的对象以达到功能复用和扩展的目的, 尽量使用合成/聚合而不要使用继承来扩展类的功能
优先使用合成/聚合的好处是,有助于你保持每个类的封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。

迪米特原则(law of demeter LOD)

一个对象对其他对象应该尽可能少的了解或依赖

3. 内部类

将一个类定义在另一个给类里面或者方法里面,这样的类就被称为内部类。
内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类,

3.1 成员内部类

他定义在另一个类中

class C{
    class D{

    }
}

成员内部类可以无条件访问外部类的属性和方法,但是外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法

创建内部类对象
显然成员内部类是寄生于外部类,创建内部类对象就必须先创造外部类对象。之后创建内部类有两种方式。

public class Test10 {
    public static void main(String[] args) {
        /*方式1创建成员内部类对象*/
        C c = new C();
        C.D d = c.new D();
        /*方式2创建成员内部类对象*/
        C.D d1 = c.getClassD();
    }
}
class C{
    private String name = "外部类";
    public void run(){
        System.out.println("外部类奔跑");
    }
    /*创建一个返回D对象的方法*/
    public D getClassD(){
        return new D();
    }
    /*使用内部类的属性和方法*/
    public void eat(){
        D d = new D();
        System.out.println(d.value);
        d.say();
    }
    class D{
        private String value = "DDD";
        private String name = "内部类";
        public void say(){
            System.out.println(C.this.name);
            System.out.println(name);
            run();
        }
    }
}

3.2 局部内部类

局部内部类存在于方法中。
他和成员内部类的区别在于局部内部类的访问权限仅限于方法或作用域内。

class K{
    public void say(){
        class J{
            
        }
    }
}

注意事项:局部内部类就像局部变量一样,前面不能访问修饰符以及static修饰符。

3.3. 匿名内部类

public class Test13 {
    public static void main(String[] args) {
        driveCar(new Car(){
            @Override
            public void drive() {
                System.out.println("驾驶着BMW汽车");
            }
        });
    }
    public static void driveCar(Car car){
        car.drive();
    }
}

interface Car {
    void drive();
}

分析以上代码知道静态方法driveCar需要一个Car对象,我们通过实现接口创建一个匿名类对象传递过去。事实上还可以通过继承类来创建一个匿名内部类对象。

注意事项: 匿名内部类没有构造方法。也是唯一没有构造方法的内部类。匿名内部类和局部内部类只能访问外部类的final变量。

3.4 静态内部类

静态内部类和成员内部类相比多了一个static修饰符。它与类的静态成员变量一般,是不依赖于外部类的。同时静态内部类也有它的特殊性。因为外部类加载时只会加载静态域,所以静态内部类不能使用外部类的非静态变量与方法。
同时可以知道成员内部类里面是不能含静态属性或方法的。

class U {
    static class I {
        
    }
}

3.5 内部类的好处

  1. 完善了Java多继承机制,由于每一个内部类都可以独立的继承接口或类,所以无论外部类是否继承或实现了某个类或接口,对于内部类没有影响。
  2. 方便写事件驱动程序

静态内部类对象的创建一般是 外部类.内部类 类名 = new 外部类.内部类() ;
成员内部类对象的创建一般是 外部类.内部类 类名 = 外部类对象名.new 内部类() ;

4. java数组

概念
同一种类型数据的集合。其实数组就是一个容器。

数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。

格式
元素类型[] 数组名 = new 元素类型[]{元素,元素,……};

数组常用的方法:

排序:Array.sort();
查找:Array.binarySearch();
打印:Array.toString();
复制:Array.copyof();

5.异常

异常类的结构图
技术图片

1.所有的异常都是从Throwable继承而来的,是所有异常的共同祖先。
2.Throwable有两个子类,Error和Exception。

其中Error是错误,对于所有的编译时期的错误以及系统错误都是通过Error抛出的。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。

Exception,是另外一个非常重要的异常子类。它规定的异常是程序本身可以处理的异常。异常和错误的区别是,异常是可以被处理的,而错误是没法处理的

5.1异常处理

1. 通过try...catch语句块来处理

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}
  • Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。

2. 另外,也可以在具体位置不处理,直接抛出,通过throws/throw到上层再进行处理

3. finally关键字

finally 关键字用来创建在 try 代码块后面执行的代码块。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}

java基础知识总结(二)

标签:一个   基类   run   特征   name   虚拟   兔子   throws   类的成员   

原文地址:https://www.cnblogs.com/aidawone/p/14487493.html


评论


亲,登录后才可以留言!