前言
这个东西终于有老师教了,我对一期后达到的水平没什么要求,这门课随便过了就行。那么,开始随便瞎JB写吧。
类
public class Test{
public static void main(String[] args){
System.out.println("hello");
}
}
Java中的函数不能单独存在,全部都要放在类中。一个 public class A{}
形式的类一个 .java文件最多有一个,而且这个一级的公共类(不是嵌套的)的名字和包含它的文件名应该相同。如果没有公共类,那么文件名字也应该与包含
public static void main(String[] args){}
这个入口函数的类名相同。每个类中同样可以存着入口函数,也可以没有入口函数。
属性与方法
比起C++中的类,Java中的类没有析构函数,可以不写public、private、protected限定符。麻烦的是如果要写限定符,每个函数或者变量需要单独考虑,有些加有些不加。
修饰符 | 同类 | 子类(同包) | 非子类(同包) | 子类(不同包) | 非子类(不同包) |
---|---|---|---|---|---|
public | √ | √ | √ | √ | √ |
protected | √ | √ | √ | √ | 不可以 |
无 | √ | √ | √ | 不可以 | 不可以 |
private | √ | 不可以 | 不可以 | 不可以 | 不可以 |
(包和子类的概念下面再介绍)
class _A{
private int m_a;//私有的变量
public void func(){} //公共权限的函数
protected int f1(){} //被保护的函数
void move(){} //不写限定符的是友好的,这个方法就是友好方法
}
static
class A{
int a; //实例变量
static b; //类变量
void fun(){} //实例方法
static void func(){} //类方法
}
没有static 修饰的类属性称为实例变量,反之叫类变量。放到函数上就是实例方法与类方法,类方法(用static 修饰的)只能调用该类的类方法,不能调用实例方法。而实例方法就随意了。
static修饰的变量或方法自然就和实例化无关了,可以直接通过类名来调用。
重载与this
class B{
double getArea(double x,int y){ return x*y; }
int getArea(int x,double y){return (int)(x*y);}
double getArea(float x,float y,float z){ return (x*x + y*y + z*z)*2.0; }
void func(){
System.out.println( this.getArea(1,2) ); //this的使用
}
}
重载也是C++中有过的知识,意思是允许写几个相同命名的函数,只是保证返回类型、传入参数的类型和个数不一样就行了。这么写下的几个函数自己使用就使用了,实际推导到底是哪个函数这个靠编译机自己做。
this关键字在类中函数里使用,可以通过点操作调用类中元素。
package
package module1;
package module2.module3;
//...
所有的 .java 文件都可以放在包里面,引用包时语法是 package 包名;
如果没有写这个package语句,那么 .java文件默认是一个无名包的一部分。
如果package语句引用的包有用点操作(如下面第二句),那么写了这句话的 .java 文件应该放在 module2\module3这样的目录之下。
import
//引用类库中的类
import java.applet; //包含所有的Java Applet实现的类
import java.awt; //包含抽象窗口工具集中的图形、文本、窗口GUI类
import java.awt.image; //包含抽象窗口工具集中的图像处理类
import java.lang; //包含所有的基本语言类
import java.io; //包含所有的输入输出类
import java.net; //包含所有网络功能实现的类
import java.uti;; //包含有用的数据类型类
通过import导入包中的类,一个Java文件中的import语句必须写在package语句和其他内容之间,如果没有package的话import语句当然写最开头啦。
如果要导入一个包中的所有类,可以用通配符 * 代替 import java.awt.*;
而写的具体的话就只是引用该文件的类而已(文件名毕竟和类名一样嘛)
继承
class A{} //默认继承与Object,和下面这句一样
class A extends Object{}
class Parent{ //父类
private int a;
int b;
protected int c;
public int d;
}
class Children extends Parent{ //子类继承于父类
void func(){
//a=0; error
b=1;
c=2;
d=3;
System.out.println(b+c+d);
}
}
类的三大概念,封装、多态、继承。类能封装这个就不用说了,多态由函数的重载实现函数的多态,抽象类或者接口来实现类的多态——多态就是多个不同的东西可以对应这同一个入口或者解决方案……继承就是保留其他类(被继承的类)部分的功能,又由新需求在子类上拓展出新的功能。
- Java不允许多继承,只有单继承
上转型对象
Parent p=new Child();
p.print();//Child类中重写的print
Parent p1=new Parent();
p1.print();
用一个父类对象来创建其子类,将会得到一个上转型对象p。上转型对象p与普通用父类定义的对象p1的区别是p调用重名方法时调的是子类的,其他都和p1相同。p和p1一样能调用父类的属性,父类的方法(没被重写的)
隐藏父类变量
如果有东西我又不想继承过来,那么隐藏起来就是一种解决方法。说是隐藏,其实也就是对变量的重写而已,重写的变量和父类的变量区别是类型不同。
重写方法
在子类里写一个和父类中的一模一样的方法,这就是重写该方法。
super
class Parent{
int x,y;
A(){ //默认构造函数
x=1,y=2;
}
A(int x,int y){
this.x = x, thi.y = y;
}
}
class Children extends Parent{
int z;
B(){ //默认构造函数
//super();
z=3;
}
B(int x,int y){
super(x,y);//调用父类构造函数完成对x,y的初始化
z=3;
}
}
super函数可以调用父类的构造函数,也可以操作被隐藏(重写)的类元素 :
super.x ; super.func();
。
final类&final方法
final class A{
final int fun(){}
}
final类不能被继承,final方法不能被重写(如果这个方法的类可以不是final的话,如果是那么这个方法的final关键字就没有意义)
抽象类
abstract class A{ //抽象类
public boolean move(){} //实例方法
public abstract int run();//抽象方法
}
abstract类是用于将类的特性合在一起。在C++中做设计模式时常常用没有实现的抽象类来作为几个相似类的接口。
抽象方法不能实现,需要留给子类来实现。抽象类或者是父类的对象可以定义子类的实例,所以这样的对象也叫上转型对象。
- 不允许final和abstract同时修饰。
- 抽象类不能new
接口
接口只提供方法声明,不提供方法实现
//接口的声明
interface Printable{
final int MAX=100;
void add();
float sum(float x,float y);
}
//接口的使用
class A implements Printable,Addable{} //类A使用接口Printable,Addable
class Dog extends Species implements Eatable,Sleepable //类Dog既在继承,又在使用接口
class Some implements Printable{
//接口的实现方法必须加public关键字
public float sum(float x,float y){System.out.println("sum");}
}
接口和类很像,就像类和结构体很像一样,都是在后者基础上增加衍生的。接口同样可以被继承,继承的仍然是一个接口(子接口)。
接口中的方法默认是public且abstact的,所以接口声明时可以省略这两个,但是类在实现的时候一定要加public。
- 接口中不能定义成员变量,只能定义成员常量
- 抽象类只能被单继承(实现),但是接口可以被多实现
- 抽象类是封装共有的属性和行为,而接口只封装共有的的行为
- 抽象类中的抽象方法(没有实现的)都需要abstract关键字,接口类中都是抽象方法(都不能实现),可以忽略abstract关键字
内嵌类
在一个类里定义另一个类,前者把后者看做自己的成员。内嵌类不能声明static成员,也就是不能声明类变量、类方法。
匿名类
interface faceID{
void look();
void sayHello();
}
class Vivo implements faceID{
public void look(){
System.out.println("Vivo::look");
}
public void sayHello(){
System.out.println("Vivo::hello,hello");
}
}
class Apple{
public void faceID(faceID a){
System.out.println("Apple::faceID");
a.look();
a.sayHello();
}
}
public class Test{
public static void main(String[] args){
Apple apple=new Apple();
apple.faceID(new Vivo());
apple.faceID(new faceID(){//用接口或抽象类来定义一个匿名类,并实现其所有接口
public void look(){
System.out.println("Apple::look");
}
public void sayHello(){
System.out.println("Apple::hello");
}
});
}
}
//result
Apple::faceID
Vivo::look
Vivo::hello,hello
Apple::faceID
Apple::look
Apple::hello
匿名就是无名,没有给定义的类分配一个名字,所以不可能用匿名类来声明对象,只能在定义的时候创建。
匿名类不可以声明static成员。
异常类
public class Test{
public static void main(String[] args){
int n=0,m=0,t=0;
try{
t=9999;
m = Integer.parseInt("8888");
n= Integer.parseInt("12s3a");
System.out.println("我没有异常抛出")
}
catch(Exception e){
System.out.println("异常");
n=123;
}
System.out.println("n="+n+"m="+m+"t="+t);
}
}
当程序出错时,编译器用异常类Exception的相应子类创建一个异常对象,并等待处理。
有时需要抛出的异常消息比较有个性,需要自定义异常类。
//自定义异常类
class GG_Exception extends Exception{
String message;//异常的消息显示
GG_Exception(int n) {
message=n+"不是正数";
}
public String getMessage(){
return message;
}
}
class GG{
public void f(int n) throws GG_Exception{
if(n<0){
GG_Exception e=new GG_Exception(n);
throw(e);
}
double num=Math.sqrt(n);
System.out.println(n+"的平方根是"+num);
}
}
public void test(){
public static void main(String[] args){
GG gg=new GG();
try{//等着抛异常
gg.f(-12);
}
catch(GG_Exception e){
System.out.println(e.getMessage());
}
}
//result
-12不是正数
泛型(Generics)类
class Chorus<E,F>{
void makeChorus(E person,F instructor){
instructor.toString();
person.toString();
}
}
泛型和模板有点相似。语法class A<E>
声明一个泛型类,A是泛型类的名称,E是其中的泛型列表。E可以是任何对象或接口,但不能是基本数据。
通过泛型可以建立类型安全的数据结构,在使用泛型建立数据结构时,不用进行强制类型转换(不要求进行运行时类型检查)