四、类和对象2
主要内容:Java类的继承、方法的重写、覆盖、访问控制、super 关键字、多态性及其应用
1.继承
要求:Java只支持单继承,不允许多重继承
一个子类只能有一个父类
一个父类可以派生出多个子类
子类继承了父类,就继承了父类的方法和属性。
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
因而,子类通常比父类的功能更多。
在Java 中,继承的关键字用的是“extends”,即子类是对父类的“扩展”。
注意:子类不能继承父类中私有的(private)成员变量和方法。
2.访问控制
3.方法重写
在子类中可以根据需要对从父类中继承来的方法进行改造重写方法,在程序执行时,子类的方法将覆盖父类的方法。
方法重写必须和被重写的方法具有相同的方法名、参数列表和返回值类型。
重写方法不能使用比被重写方法更严格的访问权限。
4.super关键字
在Java类中使用super关键字来引用父类的成分
super可用于访问父类中定义的属性
super可用于调用父类中定义的成员方法
super可用于在子类构造方法中调用父类的构造方法
示例:public class Person {
private String name;
private int age;
public String getInfo() {
return "Name: " + name + "\nage: " + age;
}
}
public class Student extends Person {
private String school = "New Oriental";
public String getSchool(){
return school;
}
public String getInfo() {
调用父类的方法
return super.getInfo() +"\nschool: " +school;
}
}
补充:super与父类构造方法的调用
子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法
在子类的构造方法中可使用super(参数列表)形式的语句调用父类的构造方法
如果子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法
如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错
5.多态性
多态:子类的对象可以替代父类的对象使用
一个变量只能有一种确定的数据类型
一个引用类型变量可能指向(引用)多种不同类型的对象
Object o = new Person();Object类型的变量o,指向Person类型的对象
o = new Student(); Object类型的变量o,指向Student类型的对象
父类类型的变量可以指向子类的对象
Person p = new Student();
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。
Student s = new Student();
s.school = “hp”; 合法
Person p = new Student();
p.school = “hp”; 非法
正常的方法调用
Person p = new Person();
p.getInfo();
Student s = new Student();
s.getInfo();
动态绑定
Person p = new Student();
p.getInfo(); 调用Student类的getInfo()方法
在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际类型调用其相应的方法。
方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test{
public void method(Person p) {
……
p.getInfo();
}
public static void main(Stirng args[]){
Test t = new Test();
Student s = new Student();
t.method(s); 子类的对象s传送给父类类型的参数p
}
}
6.instanceof操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
public class Person extends Object {…}
public class Student extends Person {…}
public class Graduate extends Person {…}
-------------------------------------------------------------------
public void method1(Person p) {
if (p instanceof Person)
处理Person类及其子类对象
if (p instanceof Student)
处理Student类及其子类对象
if (p instanceof Graduate)
处理Graduate类及其子类对象
}
7.对象类型转换
基本数据类型的转换:
小的数据类型可以自动转换成大的数据类型
如long g=20; double d=12.0f
可以把大的数据类型强制转换成小的数据类型
如 floate f=(float)12.0 int a=(int)1200L
对Java对象的强制类型转换
从子类到父类的类型转换可以自动进行
从父类到子类的类型转换必须通过强制类型转换实现
无继承关系的引用类型间的转换是非法的
在造型前可以使用instanceof操作符测试一个对象的类型
public class Test{
public void method(Person p) {
System.out.pritnln(p.getschool()); 不推荐
if(p instanceof Student){ 推荐
Student me = (Student)p;
System.out.pritnln(me.getschool());
}
}
public static void main(Stirng args[]){
Test t = new Test();
Student s = new Student();
t.method(s);
}}
五、类和对象3
主要内容:static 关键字、final 关键字、抽象类、接口、内部类
(一)static关键字:
静态的,可以用来修饰属性、方法、代码块(或初始化块)、内部类
static修饰属性(类变量):
1.由类创建的所有的对象,都共用这一个属性
2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs 实例变量(非static修饰的属性,各个对象各自拥有一套副本)
3.类变量随着类的加载而加载的,而且独一份
4.静态的变量可以直接通过“类.类变量”的形式来调用
5.类变量的加载是要早于对象。所以当有对象以后,可以“对象.类变量”使用。但是"类.实例变量"是不行的。
6.类变量存在于静态域中。
static修饰方法(类方法):
1.随着类的加载而加载,在内存中也是独一份
2.可以直接通过“类.类方法”的方式调用
3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法是可以调用静态的属性或静态的方法
>静态的方法内是不可以有this或super关键字的!
注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,同时被回收也要晚于非静态的结构
main方法
public static void main(String[] args){
方法体
}
1.main()是一个方法,是主方法,为程序的入口
2.权限修饰符:public protected 缺省 private ---面向对象的封装性
3.对于方法来讲:static final abstract
4.方法的返回值:void / 具体的返回值类型(基本的数据类型 & 引用数据类型),方法内部一定要有return
5.方法名:命名的规则:xxxYyyZzz。给方法命名时,要见名之意
6.形参列表:同一个方法名不同的形参列表的诸多个方法间构成重载。 形参 & 实参---方法的参数传递机制:值传递
7.方法体:方法定义的是一种功能,具体的实现由方法体操作。
代码块:
是类的第4个成员
作用:用来初始化类的属性
分类:只能用static来修饰。
静态代码块:
1.里面可以有输出语句
2.随着类的加载而加载,而且只被加载一次
3.多个静态代码块之间按照顺序结构执行
4.静态代码块的执行要早于非静态代码块的执行。
5.静态的代码块中只能执行静态的结构(类属性,类方法)
非静态代码块:
1.可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的)
2.里面可以有输出语句
3.一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行
4.每创建一个类的对象,非静态代码块就加载一次。
5.非静态代码块的执行要早于构造器
关于属性赋值的操作:
①默认的初始化
②显式的初始化或代码块初始化(此处两个结构按照顺序执行)
③构造器中;
—————————以上是对象的属性初始化的过程—————————————
④通过方法对对象的相应属性进行修改
(二)final关键字
final:最终的 ,可以用来修饰类、属性、方法
1.final修饰类:这个类就不能被继承。如:String类、StringBuffer类、System类
2.final修饰方法:不能被重写。如:Object类的getClass()
3.final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。
此常量在哪里赋值:①此常量不能使用默认初始化 ②可以显式的赋值、代码块、构造器。
变量用static final修饰:全局常量。比如:Math 类的PI
>与finally finalize()区分开
/
class D{
final int I = 12;
final double PI;
final String NAME;
public void m1(){
System.out.println(I);
// I = 10;
}
{
PI = 3.14;
}
public D(){
NAME = "DD";
}
public D(String name){
this();
//NAME = name;
}
}
(三)抽象类
重点!
abstract:抽象的,可以用来修饰类、方法
1.abstract修饰类:抽象类
1)不可被实例化
2)抽象类有构造器 (凡是类都有构造器)
3)抽象方法所在的类,一定是抽象类。
4)抽象类中可以没有抽象方法。
>当我们设计一个类,不需要创建此类的实例时候,就可以考虑将其设置为抽象的,由其子类实现这个类的抽象方法以后,就行实例化
2.abstract修饰方法:抽象方法
1)格式:没有方法体,包括{}.如:public abstract void eat();
2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。
3)若子类继承抽象类,并重写了所有的抽象方法,则此类是一个"实体类",即可以实例化
4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的!
补充:抽象类和接口的区别
1.抽象类里可以有构造方法,而接口内不能有构造方法。
2.抽象类中可以有普通成员变量,而接口中不能有普通成员变量。
3.抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。
4.抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5.抽象类中可以包含静态方法,接口内不能包含静态方法。
6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。
8.接口更多的是在系统框架设计方法发挥作用,主要定义模块之间的通信,而抽象类在代码实现方面发挥作用,可以实现代码的重用。
(四)接口
接口(interface) 是与类并行的一个概念
1.接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。
2.接口是没有构造器的。
3.接口定义的就是一种功能。此功能可以被类所实现(implements)。
比如:class CC extends DD implements AA
4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写所有的抽象方法,则此类仍为一个抽象类
5.类可以实现多个接口。----java 中的类的继承是单继承的
6.接口与接口之间也是继承的关系,而且可以实现多继承
>5,6描述的是java中的继承的特点。
7.接口与具体的实现类之间也存在多态性
(五)内部类
类的第5个成员:内部类
1.相当于说,我们可以在类的内部再定义类。
外面的类:外部类。 里面定义的类:内部类
2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里)
3.成员内部类:
3.1是外部类的一个成员:①可以有修饰符(4个)②static final ③可以调用外部类的属性、方法
3.2具体类的特点:①abstract ②还可以在其内部定义属性、方法、构造器
4.局部内部类:
5.关于内部类,掌握三点:
①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象)
②如何区分调用外部类、内部类的变量(尤其是变量重名时)
③局部内部类的使用
总结及补充:
面向对象的三大特性:
封装性:
① 通过私有化类的成员变量,通过公共的getter和setter方法来调用和修改
② 还可以对类的其他结构进行“封装”
③ 权限修饰符:public protected 缺省 private
继承性:
通过让一个类A继承另一个类B,就可以获取类B中的结构(主要的:属性、方法、构造器)。子类:类A 父类:类B
>java中的类的继承性:单继承的。
多态性:
①体现:方法的重载与重写 ; 子类对象的多态性 Person p = new Student();
②子类对象多态性的使用:虚拟方法调用。
③向上转型 向下转型 Student s = (Student)p; //建议在向下转型之前: if ( p instanceof Student)避免出现ClassCastException的异常
其它关键字:
1. this:修饰属性、方法、构造器 。表示:当前对象或当前正在创建的对象
2. super:修饰属性、方法、构造器。显式的调用父类的相应的结构,尤其是子父类有重名的方法、属性
3. static : 修饰属性、方法、代码块、内部类。随着类的加载而加载!
4. final:修饰类、属性、方法。表示“最终的”
5. abstract : 修饰类、方法
6. interface:表示是一个接口,(接口是与类并列的一个结构)。类与接口之间同时“implements”发生关系。
7. package import 。。。
>abstract不能修饰属性、构造器、不能与final static private共用。