Java作为一种面向对象语言。学习java必须懂得基本概念:
- 多态
- 继承
- 封装
- 抽象
- 类
- 对象
- 实例
- 方法
- 重载
对象就是我们周围的各种各样的事物。例如:衣服、盘子、宠物、朋友、电脑等。
对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。
每个对象都有一些状态(属性)。例如:
衣服:{颜色,长度,面料…}。
猫:{名字,情绪,饥饿,}。
有些对象会作出一些行为。例如:
猫:{名字,情绪,疲劳,饥饿…
发怒,玩耍,吃食,睡觉…}。
对象的行为会改变对象的状态。例如:
玩耍 → 疲劳=True
睡觉 → 疲劳=False
吃食 → 饥饿=False
对象的状态会影响对象的行为。例如:
if( 饥饿 == False) → 吃食 return failure
构造方法
每个类都有构造方法。
如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。
构造方法的名称必须与类同名,一个类可以有多个构造方法。
下面是一个构造方法示例(声明类的方法):
public class Dog{//类(有多个构造方法)
public Dog(){//构造方法(与类同名)
}
public Dog(String name){
// 这个构造器仅有一个参数:name
}
}
创建对象
对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:
- 第1步.声明:声明一个对象,包括对象名称和对象类型。
- 第2步.实例化:使用关键字new来创建一个对象。
- 第3步.初始化:使用new创建对象时,会调用构造方法初始化对象。
下面是一个创建对象的例子: Dog myDog = new Dog( "tommy" );
public class Dog{//对象小狗
public Dog(String name){//用的构造方法
//这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public static void main(String []args){
// 下面的语句将创建一个Dog对象
Dog myDog = new Dog( "tommy" );
}
}
输出:
小狗的名字是 : tommy
访问实例变量和方法
通过已创建的对象来访问成员变量和成员方法,如下所示:
/* 实例化对象 */
ObjectReference = new Constructor();
/* 访问类中的变量 */
ObjectReference.variableName;
/* 访问类中的方法 */
ObjectReference.MethodName();
实例:
public class Puppy{
int puppyAge;
public Puppy(String name){
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public void setAge( int age ){
puppyAge = age;
}
public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
}
public static void main(String []args){
/* 创建对象 */
Puppy myPuppy = new Puppy( "tommy" );
/* 通过方法来设定age */
myPuppy.setAge( 2 );
/* 调用另一个方法获取age */
myPuppy.getAge( );
/*你也可以像下面这样访问成员变量 */
System.out.println("变量值 : " + myPuppy.puppyAge );
}
}
小狗的名字是 : tommy 小狗的年龄为 : 2 变量值 : 2
类是对象的蓝图
)类是对象的蓝图,对象是类的实例,如同绘图员可以绘制设备的蓝图,蓝图可以在制造实际设备时使用很多次。
类是软件的蓝图,你可以用类,来实例化许许多多个别的对象。
在类中定义了一套数据元素状态(属性)和一套行为(方法)。行为用来操作对象,以及完成相关对象之间的交互。
属性和方法都叫做成员。例如:交通工具对象必须保存两个属性:最大载重量和当前载重量;装载集装箱的方法要始终跟踪这两个属性。
public class Dog{//对象狗,(声明类)
//以下是属性/状态,(声明属性)
String breed;//种类 int age;//年龄 String color//颜色
//以下是dog类方法/行为,(声明方法)
void barking(){//狗叫 } void hungry(){//饥饿 } void sleeping(){//睡觉 }}
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
Java 继承
继承的概念
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
生活中的继承:
兔子和羊属于食草动物类,狮子和豹属于食肉动物类。
食草动物和食肉动物又是属于动物类。
所以继承需要符合的关系是:is-a,父类更通用,子类更具体。
虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。
抽象:就是对事物的状态、行为进行概括、总结、描述。
软件开发过程可分为五个阶段:(分析、设计)、实现、测试、发布。
抽象对应于软件工程的分析、设计阶段。
分析:就是确定我们开发的系统想要实现什么。在分析阶段可以定义一组操作者,以及系统必须完成的行为。此外,还要定义一组主对象,系统在主对象之间完成操作、行为、交互。行为的描述要足够详细。
设计:就是确定系统如何实现要达到的目标。在设计阶段,要生成操作者、行为、主对象的模型。
例如,我们可以对一个轮船公司的软件工程作出下面的抽象:
软件必须支持一个轮船公司。
轮船公司保持一队运输集装箱的交通工具。
在调出一个交通工具时,集装箱的重量是唯一的重要因素。
轮船公司有两种类型的交通工具:卡车和内河驳船。
集装箱用千克标重,计算交通工具的引擎功率时,需要用牛顿表示的交通工具的总重量。
图形用户接口用来跟踪向交通工具中装载的集装箱。
一些报表用来生成车/船队的记录。
然后:
凭借这些需求分析,我们可以作出高水平的设计:
系统中必须用对象表示公司、两种交通工具。
公司是多个交通工具对象的集合。
还应该包括报表、图形用户接口等对象。
抽象类总结规定
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,如图所示(打印机就是多态的形式):
多态性是对象多种表现形式的体现。
现实中,比如我们按下 F1 键这个动作:
- 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
- 如果当前在 Word 下弹出的就是 Word 帮助;
- 在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
比如:
Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
以下是一个多态实例的演示,详细说明请看注释:
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型 ,动物有多种形态
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal { //Animal动物是多态,类似打印机
abstract void eat(); //动物都会吃
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼"); //这个动物吃的事鱼,类似打印机,一个打黑白
}
public void work() {
System.out.println("抓老鼠"); //这个动物会抓老鼠
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头"); //这个动物吃的是骨头,类似打印机,一个打彩色
}
public void work() {
System.out.println("看家"); //这个动物会看家
}
}
T执行以上程序,输出结果为:
吃鱼 抓老鼠 吃骨头 看家 吃鱼 抓老鼠
多态的实现方式
方式一:重写:
这个内容已经在上一章节详细讲过,就不再阐述,详细可访问: Java 重写(Override)与重载(Overload) 。方式二:接口
1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
方式三:抽象类和抽象方法
详情请看 Java抽象类 章节。
Java 重写(Override)与重载(Overload)
重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。
在面向对象原则里,重写意味着可以重写任何现有方法。
方法的重写规则
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
Super关键字的使用
当需要在子类中调用父类的被重写方法时,要使用super关键字。也就是先访问父类
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
重写与重载之间的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
重写和重载的总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
- (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
- (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
Java 封装
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装的优点
1. 良好的封装能够减少耦合。
2. 类内部的结构可以自由修改。
3. 可以对成员变量进行更精确的控制。
4. 隐藏信息,实现细节。
//封装:不想给别人看的进行封装,可以告诉的就公开
class Student{
private String name;//private私有的,加这个只能在自己的类访问它,其他类不能访问,即不想告诉别人,隐藏起来
private int age;
private char gender;//
//给gender提供一个共有的方法setGender,也就是可以公开的方法
public void setGender(char gender){//命名规范,看到set开头就知道给成员属性做设置
if(gender=='男'||gender=='女'){//增加控制用户乱输入,即只能输入男或女,不能输入其他内容
this.gender=gender;
}else{
System.out.println("请输入正确的性别");//输入其他内容就提醒
}
}
//不能直接输出了,需要定义一个方法
public char getGender(){//命名规范,看到get开头取得意思
return this.gender;//return gender;可以这么写,因为没有重名,加个this容易分清
}
}
public class A6_12{
public static void main(String[] args){
Student one=new Student();
//one.gender('f');这个是没有加private前可以直接传值,加private后还这么写就会报错
one.setGender('男');
System.out.println(one.getGender());
}
}
看完还不懂面向对象?那只能建议你到网站详细学习咯!还不行最好找个视频看看,0基础推荐51自学网,有基础的能看的下文字和书籍的推荐以下网址。