Edu的题重做笔记——Java

121 阅读12分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一.通关任务一(面向对象思想)

  • 构造器:new就是一个构造器,作用是:①分配空间;②赋初始值(避免错误,简化输入);
  • new Object(Parameters)构造器调用构造函数,传参为了赋初始值;
  • 对象的基本元素是:属性和方法 、类成员(属性和方法)。属性最为重要,属性的集合是一个状态,方法是一个状态到另一个状态的桥梁;
  • 封装:属性和处理属性的方法集合起来。把数据及数据的操作方法放在一起,作为一个相互依存的整体,即对象。

1.1 封装

封装: 访问权限的控制常被称为是具体实现的隐藏。把数据和方法包装进类中,以及具体实现的隐藏共同被成为封装。

img

  • public:可以被所有其他类访问;
  • protected:自身、子类、及同一个包中类(接受包外的子类访问);
  • default:同一包中的类可以访问,声明时没有加修饰符,认为是friendly(拒绝一切外包访问);
  • private:只能被自己访问和修改。

类的访问控制符只有三种:publicprivateprotected

default是无访问控制符。

1.2 继承

在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象。继承使子类拥有父类所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。子类不能继承父类的构造函数,只是显式或隐式调用,可以从子类调用超类的构造函数。

new创建子类的对象时,若子类没有带参构造函数,将先执行父类的无参构造函数,然后再执行自己的构造函数。父类定义了有参的构造函数后,可以不定义无参的构造函数,系统也不会提供默认的无参构造函数。这时子类只能调用父类的有参构造函数。 Java类是单继承,Java接口可以多继承。类可以实现多个接口,接口可以继承(扩展)多个接口。先继承后实现接口。

组合和继承

组合是指在新类里面创建原有的类的对象,重复利用已有类的功能。(“has - a”) 组合和继承都允许在新的类中设置子对象,只是组合是显式的,而继承是隐式的。组合中的整体类和继承中的子类对应,组合中的局部类和继承中的父类对应。

组合和继承的选择规则:

① 除非两个类之间是“is - a”的关系,否则不要轻易地使用继承。过多的使用继承会破坏代码的可维护性,当父类修改时,会影响所有继承他的子类,增加了程序维护的难度和成本。

②不要仅仅为实现多态而使用继承,如果类之间没有“is - a”关系,可以通过实现接口与组合的方式来达到相同的目的。

1.3 构造函数

用来在对象实例化时初始化对象的成员变量。

特点:

① 方法名必须和类名相同,不能有返回值(也不能为void);

② 一个类可以有多个构造函数,没有定义的话,编译器会在源代码编译成字节码文件的过程中会提供一个没有参数的默认的构造方法。若定义后,不会再创建默认的构造方法;

③构造函数的参数有(0到多个);

④构造函数在对象实例化时会被自动调用,且只运行一次;普通方法是在程序执行到时才调用且可以被该对象调用多次;

⑤构造函数的作用是完成对象的初始化;

⑥构造函数不能被继承,不能被覆盖,能被重载;

⑦子类可以通过super()关键字来显示调用父类的构造函数,父类没有提供无参构造,子类的构造函数中必须显式得调用父类的构造函数;

⑧父类和子类都没有定义构造函数时,编译器都会为父类生成一个默认的无参构造,给子类也生成一个默认的无参的构造函数;

⑨构造方法会在成员变量之后初始化;

⑩构造方法不能被staticfinalsynchronizeabst\fractnative修饰,但可以被publicprivateprotect修饰。

在继承的时候,父类当然也有构造方法,如果你要创建子类的对象,那么执行的过程首先是调用父类的无参构造方法生成父类的对象,然后再调用子类的无参构造方法来生成子类对象。继承的时候都是先生成父类的对象,然后再生成子类的对象。

通过使用this关键字带上参数,可以在一个构造函数中调用另外一个构造函数。这是this除了单纯表示“当前对象”(注意是针对对象而不是类的概念)之外的第二个作用。但是注意3点:

① 必须放在第一行;

②只能调用一个其它的构造函数。(也许可以这样理解,正是因为有了第一点,如果可以调用多个的话,那么就无法放在“第一行”,所以只能允许一次调用);

③只能是构造函数调用构造函数,普通函数无法调用构造函数。

1.4 super()和this()

  • super()关键字表示超类的意思,当前类是从超类继承而来。 this表示当前对象;
  • 只有在重写(Override)父类的方法中,子类要调用继承自父类的方法,才使用super关键字; 使用super()或者this()方法是必须放在构造函数的第一行。
  • 由于this函数指向的构造函数默认有super()方法,所以规定this()super()不能同时出现在一个构造函数中。 因为static方法或者语句块没有实例时可以使用,而此时不需要构造实例,所以不能用this()super()

二.通关任务二

2.1重写和重载

方法重载(overload):

  • 必须是同一个类;
  • 方法名(也可以叫函数)一样;
  • 参数类型不一样或参数数量或顺序不一样;
  • 不能通过返回值来判断重载。

方法的重写(override)子类重写了父类的同名方法,两同两小一大原则:

  • 方法名相同,参数类型相同;
  • 子类返回类型是父类返回类型的子类;
  • 子类抛出异常小于等于父类方法抛出异常;
  • 子类访问权限大于等于父类方法访问权限;

img

  • 在重写中,运用的是动态单分配,根据new的类型确定对象,从而确定调用的方法;
  • 在重载中,运用的是静态多分配,根据静态类型确定对象,不能根据new的类型确定调用方法;
  • 多态中,Father f = new Son()

成员变量:编译运行参考左边;

成员函数:编译看左边,运行看右边;

静态函数:编译运行看左边。

2.2 abst\fract(抽象类)和interface(接口)

抽象类

  • abst\fract修饰的类表示抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化;
  • abst\fract修饰的方法表示抽象方法,抽象方法没有方法体。抽象方法用来描述系统具有什么功能,但不提供具体的实现,把具体实现留给继承该类的子类。

抽象类特点:

  • 含有抽象方法的类必须声明为抽象类(不管其中是否有其他方法);
  • 抽象类可以没有抽象方法,可以有普通方法;
  • 抽象类必须被继承,抽象方法必须被重写(若子类还是抽象类,不需要重写);
  • 抽象类不能被实例化(不能直接构造一个该类的对象)。

抽象方法特点:

  • 在类中没有方法体(抽象方法只需声明,而不需实现某些功能);
  • 抽象类中的抽象方法必须被实现;
  • 如果一个子类没有实现父类中的抽象方法,则子类也变成了一个抽象类。

接口 interface 中的方法默认为**public** abst\fractpublicabst\fract可以省略),变量默认为public static final;类中的方法全部都是抽象方法。只有声明没有实现,在不同类中有不同的方法实现。

不同点

  • 接口中只能包含抽象方法和默认方法,不能为普通方法提供方法实现;抽象类中可以包含普通方法;
  • 接口里不能定义静态方法(jdk1.8下可以定义static方法),抽象类可以定义静态方法;
  • 接口中只能定义静态常量,不能定义普通成员变量;抽象类即可以定义变量又可以定义静态常量;
  • 接口中不包含构造器,抽象类里可以包含构造器,抽象类中的构造器并不是用于创建对象,而是让其他子类调用这些构造器来完成抽象类的初始化操作;
  • 接口里不能包含初始化块,但抽象类可以包含;
  • 一个类最多只能有一个父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

共同点

  • 接口和抽象类都不能被实例化,都位于继承树的顶端,用于被其他类实现的继承;
  • 接口和抽象类都可以包含抽象方法,实现接口和继承抽象类的普通子类都必须实现这些方法。

img

2.3final关键字

  • final修饰的,就是最终类,不能被继承;
  • final修饰的方法,就是最终方法,最终方法不能被重写
  • final修饰一个引用变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。修饰基本数据类型变量时,内容不能变。
  • final成员变量必须在初始化代码块或在构造器中初始化。

作用:

  • final类:如果一个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计成final类;
  • final方法:①把方法锁定,防止任何继承类修改它的意义和实现。②高效,编译器在遇到调用final方法时候会转入内嵌机制,大大提升执行效率。

2.4static关键字

  • static修饰的变量称为静态变量,静态变量属于整个类,而局部变量属于方法,只在该方法内有效。static不能修饰局部变量。static方法内部不能调用非静态方法;
  • 静态变量只能在类主体中定义,不能在方法中定义;
  • static变量只会创建一份,不管创建几个对象,都共用一个变量。

类方法指被static修饰的方法,无this指针。其他的就是实例方法。类方法可以调用其他类的static方法。

类方法和对象方法的区别:

1、 类方法是属于整个类的,而实例方法是属于类的某个对象的。

由于类方法是属于整个类的,并不属于类的哪个对象,所以类方法的方法体中不能有与类的对象有关的内容。即类方法体有如下限制:

  • 类方法中不能引用对象变量;
  • 类方法中不能调用类的对象方法;
  • 在类方法中不能使用superthis关键字。(this表示当前类的对象,由static修饰的方法是类直接调用,不需要创建对象,所以不能用this);
  • 类方法不能被覆盖。

2、与类方法相比,对象方法几乎没有什么限制:

  • 对象方法中可以引用对象变量,也可以引用类变量;
  • 对象方法中可以调用类方法;
  • 对象方法中可以使用superthis关键字。

static关键字的作用

  • 为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关;实现某个方法或属性与类而不是对象关联在一起;
  • 静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间。

2.5 多态

  • 定义:不同类的对象对同一消息做出响应。同一消息可以根据发送对象的不同而采用多种不同的行为方式;
  • 多态存在的三个必要条件:继承、重写、父类引用指向子类对象;
  • Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载;
  • 父类引用指向子类对象,该引用不能再访问子类新增的成员。Animal cat = new Cat()与直接new一个父类实例(Animal a = new Animal())的区别? 答:当父类是接口和抽象类时,不能实例化,只能运用多态,向上转型。普通类中,可以在子类中重写父类中的方法,这样就可以访问子类中的重写方法。

\