# 类和方法的创建
# 创建类和方法
# 创建类
还记得在Step1中创建主类的操作吗? 现在我们在rinya.bukkit.helloworldplugin
包中创建一个DemoClass
类来试试手.
这次不同的是, rinya.bukkit.helloworldplugin
包已经被创建好了, 你不需要右键src
创建类了, 那样你还需要输入类名. 这次请直接右键rinya.bukkit.helloworldplugin
包, 这样类将会直接创建在这个包里.
这样, 类就创建好了.
我们说的类都被存到了这些以.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语言的角度去解释最开始我们阐述的Animal
、Dog
和Cat
的关系:
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
指定的主类加载读取. 也就是, 主类是一个插件的入口.
onLoad
、onEnable
和onDisable
方法都是父类的方法, 我们在我们的插件主类里将它们覆写了.
插件被加载后, 在服务端刚刚启动时会调用插件的onLoad
方法(我们没写, 所以相当于是空的), 服务器地图等数据被加载完毕后会调用插件的onEnable
方法(我们在里面写了System.out.println("Hello World!");
), 服务端关闭或插件被卸载时, 会调用插件的onDisable
方法(我们里面什么也没写).
这就是我们之前写的插件的工作原理了!