Java面向对象的四个特征
1.抽象:
抽象——就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。(就是把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来一般叫做类或者接口。)抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是数据抽象,二是过程抽象。
数据抽象——就是用代码的形式表示现时世界中一类事物的特性,就是针对对象的属性。比如建立一个鸟这样的类,鸟都有以下属性:一对翅膀、两只脚、羽毛等。抽象出来的类都是鸟的属性,或者成员变量。
过程抽象——就是用代码形式表示现实世界中事物的一系列行为,就是针对对象的行为特征。比如鸟会飞、会叫等。抽象出来的类一般都是鸟的方法。
2.继承:
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。因此可以说,继承是为了重用父类代码,同时为实现多态性作准备。
3.封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。
4. 多态性:
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。总的来说,方法的重写、重载与动态链接构成多态性。Java引入多态的概念原因之一就是弥补类的单继承带来的功能不足。(为规避C++中多继承造成的复杂继承问题,java采用单继承。)
动态链接——对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态链接。
注意:继承与重载:一是子类与父类的关系,二是重载方法的调用问题。
子类对象可以直接当成父类对象使用,但反过来就不可以。举例来说,人是父类,学生是人的子类,所以学生对象一定具备人对象的属性,但是人对象就未必具有学生对象的特性。所以学生对象可以当做人对象来使用,但是人对象就不能当做学生对象使用。注意当把子类对象当成父类对象使用时,子类对象将失去所有的子类特性,只保留与父类同名的属性和方法(同名方法不仅是函数名相同,而且参数类型也要一样,否则不予保留)。此时可以对父类方法进行重写。
一个类中如果定义了重载的方法,则系统在调用方法时,会根据参数的类型自动选择调用合适的方法。
java面向对象
面向对象 封装的原则 要求使对象之外的部分不能随意存取对象的内部数据,从而有效避免了错误对它的“交叉感染”,使软件错误能局部化,降低排错难度
继承
所有的类都继承自java.lang.Object,一些常用的方法:
equals():比较两个对象引用时否相同。
getClass():返回对象运行时所对应的类的表示,从而得到相应的信息
toString():返回对象字符串表示
finalize():用于在垃圾收集前清除对象
notify(), notifyall(), wait(): 用于多线程处理中的同步
子类(subclass)对父类(superclass,超类)的继承
子类不能继承父类中访问权限为private的成员变量和方法。
子类可以重写父类的方法,及命名与父类同名的成员变量。
Java不支持多重继承
创建子类
class SubClass extends SuperClass {
...
}
成员的隐藏和方法的重写
子类通过隐藏父类的成员变量和重写父类的方法,可以把父类的状态和行为变为自身的状态和行为。
多态性 子类继承父类后,同一个方法有不同的表现
体现在两个方面:方法重载实现的静态多态性(编译时多态),方法重写实现的动态多态性(运行时多态)
重写方法的调用原则:子类重写父类的方法,调用子类方法;反之,调用父类的方法
一个对象可以引用子类的实例来调用子类的方法
eg: B继承A,A的对象a引用B的实例,调用B的方法callme()
1 import java.io.*;
2 class A {
3 void callme() {
4 System.out.println("Inside A's callme()) method");
5 }
6 }
7
8 class B extends A {
9 void callme() {
10 System.out.println("Inside B's callme() method");
11 }
12 }
13
14 public class Dispatch {
15 public static void main(String args[]) {
16 A a = new B(); // 引用子类的实例
17 a.callme();
18 }
19 }
类的实现 类声明
[public][abstract|final] class className [extends superclassName] [implements interfaceNameList] {} 修饰符public, abstract, final说明类的属性 className为类的属性 superclassName为父类的名字 interfaceNameList为类所实现的接口列表
类体 class className { [public | protected | private] [static] [final] [transient] [volatile] type variableName; // 成员变量 [public | protected | private] [static] [final | abstract] [native] [synchronized] returnType methodName( [paramList]) [throws exceptionList] {statements}; //成员方法 }
成员变量 [public | protected | private] [static] [final] [transient] [volatile] type variableName; // 成员变量 static: 静态变量(类变量) final: 常量 transient:暂时性变量,用于对象存档 volatile:共享变量,用于并发线程的共享
成员方法 [public | protected | private] [static] [final | abstract] [native] [synchronized] returnType methodName( [paramList]) [throws exceptionList] {statements}; //成员方法 static: 类方法,可通过类名直接调用 abstract: 抽象方法,没有方法体 final:方法不能被重写 native:集成其他语言的代码 synchronized:控制多个并发线程的访问
Java类中的访问修饰符:
private:类中限定为private的成员,只能被这个类本身访问。如果构造方法为private,则其他类不能实例化该类。
default:不加任何访问权限,可以被这个类本身和同一个包中的类访问。
protected:类中限定为protected的成员,可以被这个类本身、它的子类和同一个包中的其他类访问。
public:类中被限定为public的成员,可以被所有类访问。
final关键字可以修饰类、类的成员变量和成员方法,但作用不同
修饰成员变量:称为常量,须给出初始值
修饰成员方法:该方法不能被子类重写
修饰类:类不能被继承
super: 访问父类的成员
访问父类被隐藏的成员变量,如super.variable;
调用父类中被重写的方法,如super.Method([paramlist]);
调用父类的构造函数,如super([paramlist]);
eg:
1 import java.io.*; 2 class SuperClass { 3 int x; 4 5 SuperClass() { 6 x = 3; 7 System.out.println("in SuperClass: x = " + x); 8 } 9 10 void doSomething() { 11 System.out.println("in SuperClass.doSomething()"); 12 } 13 } 14 15 class SubClass extends SuperClass { 16 int x; 17 18 SubClass() { 19 super(); 20 x = 5; 21 System.out.println("in SubClass: x = " + x); 22 } 23 24 void doSomething() { 25 super.doSomething(); 26 System.out.println("in SubClass.doSomething()"); 27 System.out.println("Super.x = " + super.x + "sub.x = " + x); 28 } 29 } 30 31 public class Inhereritance { 32 33 public static void main(String chars[]) { 34 SubClass sc = new SubClass(); 35 sc.doSomething(); 36 } 37 }
简单数据:值类型 复合数据:引用类型
1 import java.io.*;
2 public class PassTest {
3 float ptValue;
4
5 public static void main(String args[]) {
6 int val;
7 PassTest pt = new PassTest();
8 val = 11;
9 System.out.println("Original int Value is:"+val);
10 pt.changeInt(val);
11 System.out.println("Int Value after Change is:"+val);
12 pt.ptValue = 101f;
13 System.out.println("Original ptValue is:"+pt.ptValue);
14 pt.changeObjectValue(pt); // 引用类型的参数
15 System.out.println("ptValue after change is:"+pt.ptValue);
16
17 }
18
19 public void changeInt(int value) {
20 value = 55;
21 }
22
23 public void changeObjectValue(PassTest ref) {
24 ref.ptValue = 99f;
25 }
26 }
简单数据类型作为参数传递时,为值传递;复合数据类型作为参数传递时,为地址传递
方法体 方法的实现。方法体中局部变量若与成员变量同名,局部变量将屏蔽成员变量。