0%

javaOOP

按值传送

在java中,若将对象实例作为变量传送给方法时,自变量的值是对对象的引用。

重载方法名

java依靠参数列表来区分不同的重载的方法

java构造方法

java的默认构造方法会为各个域的值赋空(null)或赋0。

java构造方法重载时常常借助this关键字

finalize()方法

相当于C++中的析构方法,用于释放对象所占用的系统资源。

this引用

在java中,常常不需要像python那样,总是用类似self.的this.来指明类中的对象.

java继承与extends关键字

格式:

1
2
3
public class A extends B{
...
}

表面A派生于B

子类拥有父类所有变量和方法

单重继承

若一个类有父类,则其父类只能有一个

子类不能从父类继承构造方法

只有两种方法能让一个类得到一个构造方法:一,自己编写一个;二,不编写,系统默认给予

子类不能访问父类的私有元素

转换对象

假设Employee是Manager和Contractor的父类

那么:

1
2
3
4
5
6
// 合法
// 此时e可访问Employee的变量和方法,却不能访问Manager独有的
Employee e = new Manager();

// 不合法
Manager m = new Employee();

Employee类型的引用指向一个对象,但分不清该对象是Employee类还是Manager类还是Contractor类,则:

1
2
3
4
5
6
7
8
9
10
11
12
public void method(Employee e) {
if (e instanceof Manager) {
// 此时e只能访问Employee的变量和方法,若想要访问Manager的,需要转换引用
Mnager m = (Manager)e; // m能够访问Manager的变量和方法
}
else if (e instanceof Contractor){
...
}
else {
...
}
}

转换引用的类之间必须要有继承关系

异类集合

可以创建有公共祖先的任何元素的集合

1
2
3
Employee [] staff = new Employee[1024];
staff[0] = new Manager();
staff[1] = new Employee();

super关键字

若子类已重写父类的方法,但子类还想访问,则可用super关键字

super.method()访问的不一定是父类自由的,也可能是父类从祖先继承来的

重写规则

  • 重写方法允许访问的权限不能比原方法小
  • 抛出的异常不能比原方法多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 这样写是错的
class SuperClass{
public void method1(){
...
}
public void method2(){
}
}

class SonClass extends SuperClass{
private void method1(){
...
}
public void method2() throws IOException{
}
}

父类构造方法的调用

Java要求父类的对象要在子类运行前完全初始化

借助super()初始化

java包

基本概念

编译单元:一个java源代码文件。规定一个编译单元中只能有一个public类,且该类名名称与文件相同

支撑类:编译单元中其它的类

包机制:用于类名空间的管理

包:类的容器,利用包来划分名字空间,分隔类名空间

设文件声明:

1
package java.awt.image

则此文件需放在java\awt\image目录下

import语句

设已定义包:

1
2
3
4
package mypackage;
public class MyClass{
...
}

则在使用该类的办法:

1
2
3
4
mypackage.MyClass m = new mypackage.MyClass();

import mypackage.*
MyClass m = new MyClass();

类成员

包括类变量和类方法

4zY9yT.png

类变量

有时被称为静态变量,使用static关键字定义,在支撑类中定义的类变量能被包中所有成员访问,若其在public类中调用,还可被其它包访问

访问方式:类名.类变量

类方法

同样使用static定义

访问方式:类名.类方法

调用类方法的限制:

  • 静态方法只能使用其内部定义的参数或静态变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 错误引用
public class Wrong{
int x;
public static void main(String args[]){
x = 9;
}
}
// 正确
public class wrong {
int x;

public static void main(String args[]) {
hello_world h = new hello_world();
h.x = 9;
}
}
  • 静态方法不能被重写
1
2
3
4
5
6
7
8
// 错误写法
class Super{
static void noOverload(){}
}

class Sub{
void noOverload() {}
}

关键字final

一个变量被标记为final,则会成为一个常量;一个方法被final修饰,则不能被重写;一个类被定义为final,则不能有子类。

终极类

错误写法:

1
2
3
4
5
6
7
8
final public class FinalClass{
int memberar;
void memberMethod() {};
}
class SubFinalClass extends FinalClass{
int submembervar;
void subMemberMethod;
}

终极方法

1
2
3
4
5
6
7
8
9
10
class FinalMethodClass{
final void finalMethod (){
...
}
}
class OverloadClass extends FinalMethodClass{
void finalMethod(){ // 将会报错
...
}
}

终极变量

1
2
3
4
5
6
7
8
9
class Const{
final float PI = 3.14f;
}
public class UseConst{
public static void main(String args[]){
Const myconst = new Const();
myconst.PI = 3.14159f; // 报错
}
}

若将一个引用类型变量标记为final,那么这个变量将不能再指向其他对象,但它所指对象的值可改变

1
2
3
4
5
6
7
8
9
10
class Car{
int number = 1234;
}
class FinalVariable{
public static void main(String args[]){
final Car mycar = new Car();
mycar.number = 8888; // 可以
mycar = new Car(); // 错误
}
}

抽象类

借助abstract关键字创建抽象类

示例:

1
2
3
4
5
6
public abstract class Shape{
// 定义体
}// 创建子类以使此类有用

// 抽象方法
public abstract <retrunType> <methodName>(参数列表);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
abstract class ObjectStorage{
int objectnum=0;
Object storage[] = new Object[100];

abstract void put(Object o);
abstract Object get();
}

class Stack extends ObjectStorage{
private int point=0;

public void put(Object o){
storage[point++]=o;
objectnum++;
}
public Object get(){
objectnum--;
return storage[--point];
}
}

class Queue extends ObjectStorage{
private int top=0;
private int bottom=0;

public void put(Object o){
storage[top++]=o;
objectnum++;
}
public Object get(){
objectnum--;
return storage[bottom++]
}
}

接口

接口特点:

  • 本身具有数据成员和方法
  • 数据成员一定要赋初值,且该值不能再被修改
  • 方法必须是抽象方法

使用接口的原因:

  • 用于实现抽象
  • 通过接口,实现多重继承
  • 实现松耦合

形式:

1
2
3
[接口修饰符] interface 接口名称 [extends 父类名]{
... //方法原型或静态常量
}

接口的实现:

  • 实现接口的类不从该接口的定义中继承任何行为

  • 该类的任何对象可以调用接口中定义的方法

  • 一个类可实现多个接口

  • 用implements表示该类实现的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	interface Shape2D{
doube pi=3.14;
double area;
}

class Circle implements Shape2D{
double radius;
public Circle(double r){
radius=r;
}
public double area(){
return (pi * radius * radius);
}
}

class Rectangle implements Shape2D{
int width,height;
public Rectangle(int w,int h){
width=w;
height=h;
}
public double area(){
return (width * height);
}
}

同抽象类一样,使用接口名称作为一个引用变量也是允许的,既可以声明接口类型的变量(或数组)来访问对象

1
2
3
4
5
6
7
8
9
public class VariableTester {
public static void main(String []args){
Shape2D var1,var2;
var1 = new Rectangle(5,6);
System.out.println(var1.area());
var2 = new Rectangle(2.0);
System.out.println(var2.area());
}
}

内部类

基本

也称嵌套类

特性:

  • 类名只能在定义范围内使用
  • 内部类可以使用外部类的类变量和实例变量,也可使用局部变量
  • 内部类可为abstract类型
  • 内部类可以是一个接口,需要另一个内部类来实现
  • 内部类可以被定义为private或protected
  • 内部类可以无视外部类的访问保护访问外部类成员
  • 被定义为static的内部类应视为顶层类,不能再使用局部范围或其他内部类中的数据和变量
  • 内部类不能定义static型成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Test10 {
public static void main(String[] args) {
/*方式1创建成员内部类对象*/
C c = new C();
C.D d = c.new D();
/*方式2创建成员内部类对象*/
C.D d1 = c.getClassD();
}
}
class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
/*创建一个返回D对象的方法*/
public D getClassD(){
return new D();
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "内部类";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}

匿名类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Polygon {
public void display() {
System.out.println("在 Polygon 类内部");
}
}

class AnonymousDemo {
public void createClass() {

// 创建的匿名类继承了 Polygon 类
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}

class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Polygon {
public void display();
}

class AnonymousDemo {
public void createClass() {

// 匿名类实现一个接口
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}

class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}