类和对象
1 对象是现实世界事物的模拟,它具有属性和行为
2 类是创建对象的模板,它可以创建多个具有相同属性和行为的对象
3 面向对象的三大特性包括 封装 多态和继承
4 使用class关键字来定义类
5 在创建对象时,会调用类的构造方法。构造方法并没有返回值,且方法名称与类名相同
6 Java中方法在传递参数时,使用的是值传递
7 this关键字用于表示对当前对象的引用
1 使用 this 来引用成员变量
2 使用 this 来引用构造方法
8 访问权限修饰符包括public private protected 等4种
9 static关键字用于定义类变量和类方法,可以直接使用类名调用,而不必创建类对象
说明:static 关键字需要放置在变量类型前。static 关键字需要放置在返回值类型前,如果没有返回值就放在 void 之前。
在类的内部使用 static 变量(方法)时直接使用即可。在类的外部调用 static 变量(方法)可以使用“类名.静态变量名”的方式
10 final关键字用于保证不可修改
final关键字的含义是不可变,可以用来修饰类、成员变量和成员方法。如果修饰类,则表示该类不能被继承。如果修饰成员变量,则表示该变量一旦被赋值之后就不能修改,如果修饰成员方法,则表示该方法不能被子类重写。
final关键字的一个常见用法是与static关键字组合来创建常量,例如 public static final PI = 3.1415926;
注意:Java 中的常量名通常采用大写字母的形式,如果是由多个单词组成,则中间使用下划线分割。 例如 ONE_TOW
11 包用来管理Java文件
包时Java中管理源代码文件的方式。通过使用包,具有如下优势:
1 便于区分哪些是哪些类相关的
2 在不同的包中,可以存放相同名称的类
3 可以使用包来控制访问权限
声明包的语法如下 package com.mingrisoft;
注意:使用package声明包时,该语句必须放在源代码的第一行。前面可以存在注释代码,但是不能有类定义等代码
12 注解可以为代码增加额外的信息大事并不影响代码的运行
接口、继承与多态
1 Java 中使用 interface 关键字来定义接口,在接口中可以包含常量和方法
定义接口的基本语法格式
[修饰符] interface 接口名 [extends 父接口名列表]{
[public] [static] [final] 变量;
[public] [abstract] 方法;
}
2 使用 extends 关键字可以继承类,使用 implements 关键字可以实现接口
实现接口基本语法格式
[修饰符] class <类名> [extends 父类名] [implements 接口列表]{}
3 Java 中的类可以继承一个类,可以实现多个接口
继承的基本语法格式
[修饰符] class 子类名 extends 父类名{类体}
4 通过继承,可以让子类获得父类中定义的所有成员变量和方法
5 对于继承和方法,可以在子类中进行重写
6 在重写方法时,要保证方法名称和参数与父类完全相同,并且访问权限不能缩小
7 使用 super 关键字可以调用父类中定义的构造方法
8 即使子类隐藏了父类中定义的成员变量和成员方法,还可以使用 super 关键字调用
9 使用 Override 直接可以减少重写方法时出现的错误
Override 注解用来表示被其修饰的方法重写了父类或者接口中的方法
1、 引言
面向对象编程允许你从已经存在的类中定义新的类,这称为继承。
2、 父类和子类
继承使得你可以定义一个通用的类(即父类),之后扩充该类为一个更加特定的类(即子类)。
关于继承应该注意的几个关键点
和传统的理解不同,子类并不是父类的一个子集。实际上,一个子类通常比它的父类包含更多的信息和方法。
父类中的私有数据域在该类之外是不可访问的。因此,不能在子类中直接使用。但是,如果父类中定义了公共的访问器/修改器,那么可以通过这些公共的访问器/修改器来访问和修改它们。
不是所有的“是一种”(is-a)关系都应该用继承来建模。例如:正方形是一种矩形,但是不应该定义一个 Square 类来扩展 Rectangle 类,因为 width 和 height 属性并不适合于正方形。应该定义一个继承自 GemetricObject 类的 Square 类,并为正方形的边定义一个 side 属性。
继承是用来为“是一种”(is-a)建模的。不要仅仅为了重用方法这个原因而盲目地扩展一个类。例如:尽管 Person 类和 Tree 类可以共享类似高度和重量这样的通用特性,但是从 Person 类扩展出 Tree 类是毫无意义的。一个父类和它的子类之间必须存在是“是一种”(is-a)关系。
某些程序设计语言允许从及各类派生出一个子类的。这种能力成为多重继承(multiple inheritance)。但是限制称为单一继承(single inheritance) 。如果使用 extends 关键字来定义一个子类,它只允许有一个父类。然而,多重继承是可以通过接口来实现的。
3、 使用 super 关键字
关键字 super 指代父类,可以用于调用父类中的普通方法和构造方法。
子类继承它的父类中所有可访问的数据域和方法。
3.1、 调用父类的构造方法
super()或者super(parameters);
语句super()和super(arguments)必须出现在子类构造方法的第一行,这是显示调用父类构造方法的唯一方式。
要调用父类构造方法就必须使用关键字 super,而且这个调用必须是构造方法的第一条语句。在子类汇总调用父类构造方法的名字会引起一个语法错误。
3.2、 构造方法链
在任何情况下,构造一个类的实例时,将会调用沿着继承链的所有父类的构造方法。当构造一个方法的对象时,子类构造方法会在完成自己的任务之前,首先调用它的父类的构造方法。如果父类继承自其它类,那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。这个过程持续到沿着这个继承体系结构的最后一个构造方法被调用为止。这就是构造方法链(constructor chaining)
如果要设计一个可以被继承的类,最好提供一个无参构造方法以避免程序设计错误。
一般情况下,最好能为每个类提供一个无参构造方法,以便于对该类进行扩展,同时避免错误。
3.3、 调用父类的方法
super.方法名(参数)
4、 方法重写
要重写一个方法,需要在子类汇总使用和父类一样的签名以及一样的返回值类型来对该方法进行定义。
子类从父类中继承方法。有时,子类需要修改父类中定义的方法的实现,这称为方法重写(method overriding)。
以下几点值得注意:
仅当实例方法时可访问时,它才能被覆盖。因为私有方法在它的类本身以为是不能访问的,所以它不能被覆盖。如果子类汇中定义的方法在父类汇总是私有的,那么这两个方法完全没有关系。
与实例方法一样,静态方法也能也继承。但是,静态方法不能被覆盖。如果父类中定义的静态方法在子类中被重新定义,那么在父类中定义的静态方法将被隐藏。可以使用语法:父类名.静态方法名(superClassName.staticMethodName)调用隐藏的静态方法。
5、 方法重写与重载
?重载意味着使用同样的名字但是不同的签名来定义多个方法。重写以为着在子类汇总提供一个对方法的新的实现。
注意以下问题:
方法重写发生在通过继承而相关的不同类中;方法重载可以发生在同一个类中,也可以发生在由于继承而相关的不同类中。
方法重写具有同样的签名和返回值类型;方法重载具有同样的名字,但是不同的参数列表。
6、 Object 类
Java中的所有类都继承自 java.lang.Object 类。
toString()方法
7、 多态
多态意味着父类的变量可以指向子类对象。
子类型和父类型(一个类实际定义了一种类型。子类定义的类型成为子类型,而父类的类型成为父类型)
继承关系使一个子类继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来就不成立。例如:每个圆都是一个几何对象,但并非每个几何对象都是圆。因此,总可以将子类的实例传给需要父类型的参数。
8、 动态绑定?
方法可以在沿着继承链的多个类中实现。JVM决定运行时调用那个方法。
声明类型(一个变量必须被声明为某种类型,变量的这个类型成为它的声明类型)和实际类型(是变量引用的对象的实际类)
变量调用方法由变量的实际类型决定,这称为动态绑定(dynamic binding)。
匹配方法的签名和绑定方法的实现吗是两个不同的问题。引用变量的声明类型决定了编译时匹配哪个方法。在编译时,编译器会根据参数类型、参数个数和参数顺序找到匹配的方法。一个方法可能在沿着继承链的多个类中实现。Java虚拟机在运行时动态绑定方法的实现,这是有变量的实际类型决定的。
9、 对象转换
对象的引用可以类型转化为对另一个对象的引用,这称为对象转换。
instanceof 关键字 (转换之前确保该对象是另一个对对象的实例)
为了更好地理解类型转换,可以认为他们类似于水果、苹果、橘子之间的关系,其中水果类 Fruit 是苹果类 Apple 和橘子类 Orange 的父类。苹果是水果,所以,总是可以将Apple 的实例安全地赋值给 Fruit 变量。但是,水果不一定是苹果,所以,必须进行显示转换才能将 Fruit 的实例赋值给 Apple 的变量。
对象成员访问运行符(.)优先于类型转换运算符。使用元括号保证在点运算符(.)之前进行转换
10、 Object类的equals方法
object.euqals(object o);
比较运算符 == 用来比较两个基本数据类型的值是否相等,或者判断两个对象是否具有相同的引用。如果想让equals方法能够判断两个对象是否具有相同的内容,可以在定义这些对象的类时,重写类中的euqals方法。运算符 == 要比 equals 方法的功能强大些,因为 == 运算符可以检测两个引用变量是否指向同一个对象
在子类中,使用签名 equals(SomeClassName obj) 重写euqals方法是一个常见错误,应该使用equals(Object obj)