面向对象是一种符合人类思维习惯的编程思想。现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能,这样当应用程序功能发生变动时,只需要修改个别的对象就可以了,从而使代码更容易得到维护。
(1)封装性
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装思想。采用封装思想保证了类的内部数据结构的完整性,使用类的用户不能轻易地操作类的数据结构,只能执行类允许公开的数据,这样子避免了外部操作和内部数据影响,提高了程序的可维护性。
(2)继承性
继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。继承不仅增强了代码的复用性、提高开发效率,还为程序的维护补充提供了便利。
3、多态性
多态性指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。例如,当听到“Cut”这个单词时,理发师的行为是剪发,演员的行为表现是停止表演,不同的对象,所表现的行为是不一样的。
面向对象的思想光靠上面的介绍是无法真正理解的,只有通过大量的实践去学
习和理解,才能将面向对象真正领悟。接下来的第三章、第四章将围绕着面向对象的三个特征(封装、继承、多态)来讲解Java这门编程语言。
面向对象的编程思想,力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出了两个概念,即类和对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。
类的定义
在面向对象的思想中最核心的就是对象,为了在程序中创建对象,首先需要定义一个类。类是对象的抽象,它用于描述一组对象的
共同特征和行为。类中可以定义成员变量和成员方法,其中成员变量用于描述对象的特征,也被称作属性,成员方法用于描述对象的行为,可简称为方法。
在Java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量。如果在某一个方法中定义的局部变量与成员变量同名,这种情况是允许的,此时方法中通过变量名访问到的是局部变量,而并非成员变量,请阅读下面的示例代码:
class Person{
intage=10;//类中定义的变量被称作成员变量 void speak(){
intage=60;//方法内部定义的变量被称作局部变量
System.outprintin("大家好,我今年"+age+"岁!")
}}
上面的代码中,在Person类的speak()方法中有一条打印语句,访问了变量age此时访问的是局部变量age,也就是说当有另外一个程序来调用speak()方法时,输出的值为60,而不是10。
应用程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象在Java程序中可以使用new关键字来创建对象,具体格式如下:
类名 对象名称=new类名();
例如,创建Person类的实例对象代码如下:
Person p=new Person();
上面的代码中,“newPerson()”用于创建Person类的一个实例对象,“Personp”则是声明了一个Person类型的变量p。中间的等号用于将Person对象在内存中的地址赋值给变量p,这样变量p便持有了对象的引用。
(3)类的封装
在设计一个类时,应该对成员变量的访问作出一些限定,不允许外界随意访问,这就鸳要实现类的封装。
所谓类的封装是指在定义一个类时,将类中的属性私有化,即使用private关键字来修饰,私有属性只能在它所在类中被访问,如果外界想要访问私有属性,需要提供一些使用public修饰的公有方法,其中包括用于获取属性值的get()方法和设置属性值的set()方法。
java中的权限修饰符主要包括private、public和protected,这些修饰符控制着对类和类的成员变量以及成员方法的访问。
构造方法的定义
在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法,具体如下:
方法名与类名相同
在方法名的前面没有返回值类型的声明
在方法中不能使用return语句返回一个值,但是可以单独写return语句来作为方法的结束。
与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同的属性进行赋值。
都声明为age。但是这样做又会导致成员变量和局部变量的名称冲突,在方法中将无法访问成员变量age。为了解决这个问题Java中提供了一个关键字 this来指代当前对象,用于在方法中访问对象的其它成员
public void setName(String name){
this.name=name;
}
每个对象都有生命周期,当对象的生命周期结束时
(1)在介绍静态变量和静态方法前,首先需要介绍static关键字,因为由static修饰的变量和方法称为静态变量和静态方法。
被声明为static的变量和方法被称为静态成员,静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名和“.”运算符调用静态成员,语法如下:
类名.静态类成员
(2)静态变量
在一个Java类中,可以使用static关键字来修饰成员变量,该变量被称作静态变量。静态变量被所有实例共享,可以使用“类名.变量名”的形式来访问。
注意: static关键字只能用于修饰成员变量,不能用于修饰局部变量否则编译会报错。
(3)静态方法
要实现这样的效果,只需要在类中定义的方法前加上static关键字即可,通常称这种方法为静态方法。同静态变量一样,静态方法可以使用“类名.方法名”的方式来访问,也可以通过类的实例对象来访问。
注意:在一个静态方法中只能访问用static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法在被调用时可以不创建任何对象。
在Java中,类的继承是指在一个现有类的基础上去构建一个新的类构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,如果想声明一个类继承另一个类,需要使用extends关键字。
父类
public class 父类类名{
}
子类需要继承父类
public class 子类类名 extends 父类类名{
}
当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,在Java中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。接下来分两种情况来学习一下super关键字的具体用法。
1.使用super关键字访问父类的成员变量和成员方法,具体格式如下:
super,成员变量
super,成员方法(参数1,参数2...)
2.使用super关键字访问父类构造方法,具体格式如下:
super([参数1,参数2...])
final关键字可用于修饰类、变量和方法,它有“无法改变”或者“最终的含义,因此被final修饰的类、变量和方法将具有以下特性:
1.final修饰的类不能被继承。
2.final修饰的方法不能被子类重写
3.final修饰的变量(成员变量和局部变量)是常量,只能赋值一次
final 修饰方法,被final修饰的方法,最终方法,不能被子类重写
//
定义Animal父类
//class Animal{
// //使用final关键字修饰的shout()方法后,如果子类重写这个方法,编译报错
//
// //public final void shout(){}
// public void shout(){
//
// }
//}
创建Dog类继承父类
//class Dog extends Animal{
// public void shout() {
//
// }
//}
//final修饰类,最终类,不能被继承
// class Animal{
//}
//class dog extends Animal{
//
//
//}
//final修饰成员变量
class Student{
final String name="韩强";//为成为变量赋值
//定义introduce方法,打印学生信息
public void introduce() {
System.out.println("我叫"+name);
}
}
//final修饰变量,一次赋值,终身不变
public class example07 {
public static void main(String[] args) {
//Dog dog=new Dog();//创建Dog类的对象
final int num=2;//第一次可以赋值;
System.out.println(num);
//num=4;//再次赋值,编译失败
Student stu=new Student();
stu.introduce();
}}
(1)抽象类
//抽象类的使用
// 定义抽象类Animal
abstract class Animal{
public abstract void shout(); //定义抽象方法
public void sleep() {
System.out.println("动物在睡觉");
}
}
//Animal需要子类继承来使用
//定义Dog类继承Animal抽象类
class Dog extends Animal{
//重写父类的抽象方法,实习抽象方法
public void shout() {
System.out.println("汪汪....");
}
}
//定义测试类
public class example10 {
public static void main(String[] args) {
Dog dog=new Dog();//创建Dog类的对象,创建的是抽象类的子类对象
dog.shout();
dog.sleep();}
}
(2)接口
如果在一个抽象类的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。
使用接口可以实现多重继承,一个类可以同时实现多个接口,于是可以将所有需要继承的接口放置implements关键字后使用逗号隔开,实现多个接口语法如下
修饰符 class 类名 implement 接口1,接口2....{
}
(1)多态的概念
在设计一个方法时,通常希望该方法具备一定的通用性。例如要实现一个动物叫的方法,由于每种动物的叫声是不同的,因此可以在方法中接收一个动物类型的参数,当传入猫类对象时就发出猫类的叫声,传入犬类对象时就发出犬类的叫声。在同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态。继承是多态得以实现的基础。
在Java中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。
在多态的学习中,涉及到将子类对象当作父类类型使用的情况,此种情况在
Java的语言环境中称之为“向上转型”,例如下面两行代码:
Anima1 an1=new Cacil;//将cat对象当作Ani类型来使用
Animal an2=new Dogt://将Dog对象当作Antme类型来便用
将子类对象当作父类使用时不需要任何显式地声明,需要注意的是,此时不能通过父类变量去调用子类中的特有方法。
(2)多态的类型转换
对象类型的转换在java编程中经常遇到,主要包括向上转型和向下转型操作
向上转型:将子类对象赋值给父类引用
(自动类型转换)
Animal a=new Dog();
向下转型:将父类对象赋值给子类引用
(需要进行强制类型转换)
Dog a=(Dog) new Animal();
(3)object类
在Object类中,主要包括clone(),finalize(),equals(),toString()等方法,其中常用的两个方法为equals()和toString()方法。由于所有的类都是object类的子类,所以任何类都可以重写object类中的方法。
(1)getClass()方法
getClass()方法是object类定义的方法,它会返回对象执行的Class实例,然后使用该实例调用getName()方法可以取得类的名称。语法如下:
getClass().getname();
返回参数相同,方法名相同,传入参数相同,方法体不同
(2)tostring()方法
tostring()的功能是将一个对象返回为字符串形式,它会返回一个String实例,在实际的应用中通常重写tostring()方法,为对象提供一个特定的输出的模式,当这个类转换为字符串或与字符串连接时,将自动调用用重写的tostring()方法。
在Java语言中,有两种比较对象的方式,分别为“==”运算符与equals()方法,两者区别在于:“==”比较的是两个对象引用内存地址是否相等,而equals()方法比较的是两个对象的实际内容,所以equals()方法判断出了这两个对象实际上是同一个,而“==”运算符无法做出有效判断,如果两个对象类型的不同,那么equals()方法就会认为两者都不同 。
匿名内部类
在编写Java程序时,在类里面定义的类称之为内部类(InnerClass),内部类是外部类的一个成员。Java内部类可以分为:成员内部类、方法内部类和匿名内部类等。
在前面多态的讲解中,如果方法的参数被定义为一个接口类型,那么就需要定义一个类来实现接口,并根据该类进行对象实例化。除此之外,还可以使用匿名内部类来实现接口。所谓匿名内部类就是没有名字的内部类,表面上看起来它似乎有名字,实际那不是它的名字。当程序中使用匿名内部类时,在定义图名内部类的地方往往直接创建该类的一个对象。