# 类和方法的创建

# 创建类和方法

# 创建类

还记得在Step1中创建主类的操作吗? 现在我们在rinya.bukkit.helloworldplugin包中创建一个DemoClass类来试试手.
这次不同的是, rinya.bukkit.helloworldplugin包已经被创建好了, 你不需要右键src创建类了, 那样你还需要输入类名. 这次请直接右键rinya.bukkit.helloworldplugin包, 这样类将会直接创建在这个包里.

27.jpg

这样, 类就创建好了.

28.jpg

我们说的类都被存到了这些以.java为后缀的文件中, 一个.java文件可以有多个类.

package rinya.bukkit.helloworldplugin;

public class DemoClass {

}

可以发现, 创建类的格式即class + 空格 + 名字 + 一堆花括号, 花括号内就是这个类的域, 里面的东西都是这个类里的东西.
类文件第一行应该写明这个文件所在的包, 一般这种代码由Eclipse自动生成.

在这里定义的类DemoClass与文件名DemoClass.java一致, 这个类是这个文件中的“老大”, 只有它有资格带有public.

# 编写方法

我们可以在类中创建一个方法.

package rinya.bukkit.helloworldplugin;

public class DemoClass {
    void testMethod() {

    }
}

就像这样, 我们就定义好了一个方法. 方法的定义方式是返回值类型+空格+名称+小括号括起来的参数+花括号.
上面的代码定义的方法, void代表方法没有返回值, 名字为testMethod, 小括号里什么也没有, 代表这个方法执行不需要给它任何参数.

我们编写的带有功能性的代码, 通常都应该是写在方法里.
教程之后出现的一些不完整的代码片段(没有定义类和方法), 默认都是写在了某个方法里.

# 省略包名规则

有时候在使用其他类时不一定要写它的完整类名, 你可以只写它的名字, 下面是个例子:
为了举例方便, 下面的例子没有沿用上面写的HelloWorldPlugin的代码, 仅仅是为了举个例子.

你会发现在使用TestClassTwo这个类时, 我并没有写它的包名.
这是因为TestClassTwo这个类与我们当前编写的类在同一个包内. 只要在一个包内就可以省略掉包名.
这里的new tryjava.demo.two.TestClass();没有省略包名, 因为new TestClass();指的就是这个类自己了, 而不是tryjava.demo.two.TestClass类.

也许你注意到了, new TestClassThree();这行代码有一个红色波浪线, 这代表我们的这行代码是错误的, 这些问题必须纠正才可以. 你之后的开发中还会看到黄色的波浪线, 黄色代表警告, 意思是这样写不太好, 但是程序其实也能运行.

在Eclipse中, 我们把鼠标放在画有下划线的代码上, 你会发现弹出了这样的黄色窗口:

我们可以在这里看到我们错在了哪里.
这里Eclipse告诉我们TestClassThree cannot be resolved to a type, 意思是这并不是一个确切的类型, 说明我们还没有定义这个类.
确实是这样, 我们提到只有同一个包内有这个类才可以省略掉包名, 而TestClassThree并不在与TestClass类一样的包tryjava.demo.one内, 所以包名是不可以省略的, 必须要把tryjava.demo.one.three.加上才可以.

其实, 如果这个类名称不会引起重名问题, 你可以直接使用import语句把想使用的类的包引入, 即可省略这个包名了.
比如我写了import tryjava.demo.one.three;后, 以后这个包内的类我可以随便用, 不用写完整的类名了.

Eclipse已经帮我们发现了这个问题, 其实在开发过程中, 我们几乎不写import, 都是IDE补全的.
Eclipse的黄框中已经给我们了一键补全功能, 点击Import TestClassThree(tryjava.demo.one.three)即可补全该语句.

现在代码变成了这样:

package tryjava.demo.one;

import tryjava.demo.one.three.TestClassThree;

public class TestClass {
	public static void main(String[] args) {
		new tryjava.demo.two.TestClass();
		new TestClassTwo();
		new TestClassThree();
	}
}

一切正常.

省略包名还有一种特殊情况, Java中特殊规定, 使用java.lang包内的类都可以省略包名.
你即将会见到这种特殊情况, 之后我们经常用到的String就是这样.

以上我们已经讲述了Eclipse的具体使用方式, 在今后的教程中将直接放代码, 不会大量出现截图了.

# 类的继承

# Animal、Dog和Cat的继承关系

我们可以用Java语言的角度去解释最开始我们阐述的AnimalDogCat的关系:

class Animal{} //有一个类是Animal

class Dog extends Animal{} //这里表示Dog类继承了Animal类
class Cat extends Animal{} //这里表示Cat类继承了Animal类

同一个类不能继承多个类!

# 继承方法与覆写主类方法

现在我们在Animal类里写一个方法叫做say, 让动物叫.

class Animal{
    public void say(){
        System.out.println("动物在咆哮");
    }
}

然后在main方法内创建一个Cat对象.

Cat cat1 = new Cat();
cat1.say(); //子类继承了主类, 所以可以调用主类的方法

输出内容

动物在咆哮

但是每个动物叫的声音是不一样的, 子类可以覆写主类的方法

class Cat extends Animal{
    @Override
    public void say(){
        System.out.println("喵喵喵");
    }
}

class Dog extends Animal{
    @Override
    public void say(){
        System.out.println("汪汪汪");
    }
}

现在我们创建Cat对象和Dog对象调用say方法时执行的内容就不一样了. 输出的是它们各自的叫声.
覆写的方法上面要加@Override注解.
其实@Override该注解可以省略, 但是加上以后更加规范, 它告诉JVM这是覆写主类的方法.

# 最简单的多态概念

刚才我们提到的Cat对象, 因为其Cat类继承自Animal类, 所以它本质上也是一个Animal对象.
所以一个Animal类型的变量也可以存Cat类型的对象.

Animal animal = new Cat();

# 解释先前的代码

我们之前做第一个插件时, 创建了一个HelloWorldPluginMain类, 你可能注意到了, 这个类继承了JavaPlugin类.

在一款插件中, 继承了JavaPlugin类的类才能作为主类. 一个类完整的名字是包名+英文句号+类名, 在plugin.yml中我们的main一项填写了rinya.bukkit.helloworldplugin.HelloWorldPluginMain, 其实意义就是指定这个类是插件的主类.

服务端发现插件的jar文件后, 首先就会去找plugin, 看明白这个插件的name(插件名), main(主类), 并将main指定的主类加载读取. 也就是, 主类是一个插件的入口.

onLoadonEnableonDisable方法都是父类的方法, 我们在我们的插件主类里将它们覆写了.
插件被加载后, 在服务端刚刚启动时会调用插件的onLoad方法(我们没写, 所以相当于是空的), 服务器地图等数据被加载完毕后会调用插件的onEnable方法(我们在里面写了System.out.println("Hello World!");), 服务端关闭或插件被卸载时, 会调用插件的onDisable方法(我们里面什么也没写).

这就是我们之前写的插件的工作原理了!