1.static:
代码一(类变量):
特点:1.类变量可以通过类名直接访问,而不需要创建对象
2.任何一个对象对类变量的修改,都是在统一内存单元上完成的。因此,每个对象对类变量的修改都会影响其他实例对象。
package package2;
public class Example_5_19 {
public static void main(String[] args) {
System.out.println("目前出生的人数:"+Person.totalNum);
Person Wang =new Person("Wang");
Person Liu = new Person("Liu");
Person Zhao = new Person("Zhao");
System.out.println("目前出生的人数:"+Person.totalNum);
System.out.println("目前出生的人数:"+Wang.totalNum);
}
}
class Person{
static long totalNum=10000;
int age;
String name;
String id;
//
public Person(String name){
totalNum++;
this.name=name;
age=1;
}
}
代码二(类方法):
特点:1.类方法可以通过类直接调用,而不需要创建实例对象。例如,java Application的入口main()方法被声明为static类方法,不需要创建任何对象即可调用。
2.类方法属于整个类,被调用时可能还没有创建实例对象,因此,(重点哦!)类方法内只能访问类变量,而不能直接访问实例变量和方法
3.类方法中不能使用this关键字,因为类方法不属于任何一个实例
public class Example_5_20 {
public static void main(String[] args) {
System.out.println(staticTestFunction.addUP(10,5));//类方法可以被类调用
//System.out.println(staticTestFunction.sub()); //ERROR:类不可调用实例方法
staticTestFunction test = new staticTestFunction();
System.out.println(test.sub());
}
}
class staticTestFunction{
int x=10,y=6;
static int z=9;
public static int addUP(int a,int b){ //被声明为类方法
return a+b+z; //类方法中使用类变量
}
public int sub(){
return x-y;
}
public static int addUP(){
// return x+y; //ERROR:类方法中不能使用实例变量
}
}
2.final(const ):
被final修饰的类,成员变量,成员方法均不允许继承或者覆盖。
3.abstart(virtual):
声明一个类为抽象类。
语法:abstract class <类名> [extends<父类>][implements<接口名>]{
<类主体>
}
代码:
package package2;
public class Example_5_22 {
public static void main(String[] args) {
//Animal a new Animal(); //禁止实例化抽象类
Cat2 Tom = new Cat2();
Tom.eat();
Tom.run();
}
}
abstract class Animal1{ //抽象类
String eyeColor;
String furColor;
int age;
//
public Animal1(){
age =0;
}
abstract void eat(); //抽象函数,没有方法体
abstract void run(); //抽象函数,没有方法体
}
class Cat2 extends Animal1{
void run(){
System.out.println("猫扑");
}
void eat(){
Syst`
m.out.println("吃老鼠");
}
}
4.其他修饰符(具体用法请百度):
1.volatile
2.native
3.synchronized
5.接口:
接口(interface)是java所提供的另一种重要结构。
接口是一种特殊的类,但接口与类存在本质的区别。
类有成员变量和成员方法,但接口却只有常量和抽象方法。也就是说,接口的成员必须初始化,同时接口中的方法必须声明为abstract方法。
定义:[接口修饰符] interface<接口名>[extends<父类接口列表>]{接口体}
- 接口修饰符:接口修饰符为接口访问权限,有public和默认两种类型。 public指明任意类均可以使用这个接口。 在默认情况下,只有与该接口定义在同一包中的类才可以访问这个接口,而其他包中的类无权访问该接口
- 接口名:接口名为合法的Java语言标识符
- 父类接口列表:一个接口可以继承其他接口,可通过extends来实现,其语法与类的继承相同。被继承的类接口成为父类接口,用逗号(,)分隔
- 接口体:接口体中包括接口中需要说明的常量和抽象方法。由于接口体中只有常量,所有接口中的成员变量中只能定义static和final型,在类实现接口时不能修改,而且必须用常量初始化。接口体中的方法说明与类中的方法说明形式是一样的,由于接口体中的方法说明与类中的方法说明形式一样,由于接口体中的方法为抽象方法,所以没有方法体,抽象方法的关键字abstract是可以省略的,同时成员变量的关键字final也可省略。
- 接口体中的方法多被说明成public权限
6.内部类与匿名类:
代码(内部类):
package package2;
import package2.Parcel.Destination;
public class Example_5_23 {
public static void main(String[] args) {
Parcel p = new Parcel();
Parcel.Contents c =p.new Contents(33);
Parcel.Destination d =p.new Destination("山西大同");
//Destination d = new Destination("山西太原");
p.setValue(c,d);
p.ship();
p.testship();
}
}
class Parcel{
private Contents c;
private Destination d;
private int contentsCount =0;
class Contents{
private int i;
Contents(int i){
this.i = i;
contentsCount++;
}
int value(){
return i;
}
}
class Destination{
private String label;
Destination(String whereto){
label = whereto;
}
String readLabel(){
return label;
}
}
void setValue(Contents c,Destination d){
this.c=c;
this.d=d;
}
void ship(){
System.out.println("运输"+c.value()+"到"+d.readLabel());
}
public void testship(){
c = new Contents(22);
d = new Destination("山西太原");
ship();
}
}
说明:
程序编译后生成4个类文件:Example_5_23.class,Parcel.class,Parcel$Contents.class,Parcel$Destination.class
特点:1.外部类使用内部类成员。外部类使用内部类同其他成员变量和成员方法没有区别。如在例子中,Parcel类的ship方法中可以直接使用Destination和Contents类的方法和成员变量
2.内部类使用外部类的成员。一个类把内部类堪称自己的成员,外部类的成员变量在内部类中依然有效,<b>内部类可以直接使用外部类中的成员变量和方法,即便他们是private的</b>,这也是内部类的一个好处。如果内部类与外部类有同名的成员变量,<b>可以使用:外部变量名.this来访问外部类张同名的成员变量。</b>
3.非外部类使用内部类。非外部类的其他类使用内部类,在用类名和new运算符前分别冠以外部类的名字及外部对象类;不能直接使用内部类(注释)。
代码(匿名类):
package package2;
abstract class Student5{
abstract void speak();
}
class Teacher2{
void look(Student5 s){
s.speak();
}
}
public class Example_5_24 {
public static void main(String[] args) {
Teacher2 zhang = new Teacher2();
/******************************************************/
Student5 liu = new Student5(){
void speak(){
System.out.println("这是匿名类中的方法");
}
};
/*****************************************************/
zhang.look(liu);
}
}
7.泛型类(模板):
package package2;
public class Example_5_27 {
public static void main(String[] args) {
Circle3 circle = new Circle3(10);
Cone<Circle3> oneCone = new Cone<Circle3>(circle);
oneCone.height =10;
oneCone.computeVolume();
Rctangle rectangle = new Rctangle(10,5);
Cone<Rctangle> anotherCone = new Cone<Rctangle>(rectangle);
anotherCone.height = 30;
anotherCone.computeVolume();
}
}
class Cone<E>{ //泛型类
E bottom;
double height;
public Cone(E b){
bottom = b;
}
public void computeVolume(){
String s = bottom.toString();
double area = Double.parseDouble(s);
System.out.println("体积是:"+1.0/3.0*area*height);
}
}
class Circle3{
double area,radius;
Circle3(double r){
radius = r;
}
public String toString(){
area = radius * radius * Math.PI;
return ""+area;
}
}
class Rctangle{
double sideA,sideB,area;
Rctangle(double sideA,double sideB){
this.sideA = sideA;
this.sideB = sideB;
}
public String toString(){
area = sideA * sideB;
return ""+area;
}
}
泛型接口:
代码:
package package2;
public class Example_5_28 {
public static void main(String[] args) {
Chorous4<Singer2,MusicalInstruments2> model = new Chorous4<Singer2,MusicalInstruments2>();
model.makeChorous(new Singer2(), new MusicalInstruments2());
}
}
interface Compute<E,F>{
void makeChorus(E x,F y);
}
class Chorous4<E,F> implements Compute<E,F>{
public void makeChorous(E x, F y){
x.toString();
y.toString();
}
}
class Singer2{
public String toString(){
System.out.println("好一朵美丽的茉莉花");
return "";
}
}
class MusicalInstruments2{
public String toString(){
System.out.println("|8555555555555");
return "";
}
}
遇到的坑(和本节内容无关,这几天敲代码时遇见的):
一:
用命令行编译运行代码时,需要注意:
1. javac Class.java (带后缀);
java Class(不带后缀)
2.在Class.java中不能声明所属包(或者可以声明,只是我不知道)
二:
声明对象数组时,注意每个数组元素也要初始化,及:
Student [] stu = new Student[30];
stu[0].getInfo(); //报错 Exception in thread "main" java.lang.NullPointerException ,指针指向的是空的,及指针未初始化
修改:
Student [] stu = new Student[30];
Student[0] = new Student();
Student[0].getInfo();
仔细体会未修改和修改的区别:
Student [] stu = new Student[30]只是向程序说明了有一个指向大小为30个Student数量的数组,然后分配‘数组’的空间(及相当于写了30个 Student stu1,2.3,4,5…..一样),而每一个数组元素还未向程序申请,所以需要第二行代码。
异常中最容易,最平凡出现的就是空指针的问题,一定要看仔细,当出现空指针的异常时,转到错误的内行仔细分析,冷静下来,相信总会找到问题的