Java · 减熵增长(第3篇)

Summary

Java是面向对象的语言,应用Java就要深入理解并掌握Java中类的定义、继承、访问控制、修饰符和接口等有关面向对象的内容。

  • 类的组成、初始化和调用
  • 类的继承
  • 修饰符
  • 接口

类的组成、初始化和调用

提到面向对象语言,直接想到的是的概念,类是把对象抽象出来形成一类对象的想象,类封装了一类对象的状态和方法。类包含fieldmethod
field中文叫做字段、域、域变量、属性、成员变量等,它是类的属性,通过变量来表示;method中文叫做方法,它是类的功能和操作,通过函数来表示。

作者语:类就像现实物品的一个分类,比如鞋、衣服,它使得我们能够更加高效的沟通,不仅在现实生活的对话中,也在编程的代码间。
难以想象我们现实生活中的对话是:“请帮我拿一下那边红色的用来穿在脚上走路的物品”(请帮我拿下那边红色的鞋),所以写程序要用好类的概念。

类可以实例化,也就是建立一个具体的对象,这个时候需要初始化(通常用关键字new),Java是通过构造方法constructor完成的。构造方法和类名是同名的,且不写返回值。

class Person{
  String name;
  int age;
  Person(String name, int age){
    this.name = name;
    this.age = age;
  }
}

如果类没有写构造方法,则系统生成默认构造方法(default constructor)。

class Person{
  String name;
  int age;
  //Person(){},这是系统生成的默认构造方法,编译时会补充。
}

初始化并使用对象,Person类新建一个对象p,输出p的名字,如下:

Person p = new Person();
System.out.println(p.name);

扩展:
1.如果多个方法有相同的名字,编译时可以根据方法的签名signature(参数类型和个数)识别出,即Java有方法重载overloading的能力,体现了面向对象语言的多态polymorphism。下面这段程序sayHello有两个方法,运行结果是:
Hello! My name is Xiaoming
Hello Xiaohong! My name is Xiaoming

public class Example{
  public static void main(String[] argv){
    Person p1 = new Person("Xiaoming", 18);
    Person p2 = new Person("Xiaohong", 14);
    p1.sayHello();
    p1.sayHello(p2);
  }
}
class Person{
  String name;
  int age;
  Person(String name, int age){
    this.name = name;
    this.age = age;
  }
  void sayHello(){
    System.out.println("Hello! My name is " + name);
  }
  void sayHello(Person another){
    System.out.println("Hello " + another.name + "! My name is " + name);
  }
}

2.在上述程序的构造方法中出现了关键词this,它的作用是引用字段field,添加它的目的是区分字段和局部变量。比如第一段程序构造函数中有这样一句代码:this.name = name;
this.name代表Person的字段name,而等号后面的name是构造方法的参数变量name。

类的继承

面向对象的三大核心特征是封装、多态和继承,在上一节中提到了封装和多态,这一节要谈继承。
说到继承,至少涉及两个对象,称为子类subclass和父类superclass。Java规定只能单继承,一个类只能有一个直接父类。继承符合DRY(Don't repeat yourself)原则,如果子类有和父类一致的字段或者方法,那么直接继承,不要写重复的代码。Java的继承是通过关键词extends来实现的,沿用上文Person的代码,如下:

class Student extends Person{
  String teacher;
  int grades;
  Student(String teacher, int grades, String name, int age){
    super(name, age);
    this.teacher = teacher;
    this.grades = grades;
  }
  boolean isGood(){return grades > 80;}
}

subclass能继承superclass的所有字段和非private方法,但不能继承superclass的构造方法。JDK1.5后可以用@Override标记来表示subclass对superclass同名方法的覆盖override。
上述程序的构造方法中出现了关键词super,它的作用是引用父类的字段和方法。

作者语:继承是面向对象语言中容易混乱的部分,尤其是多重继承的时候,假设A继承于B,B继承于C,而C如果又继承于A,这就是个死循环。Java单继承的规定在一定程度上增强了安全性。

包package的出现是为了解决名字空间和名字冲突,一方面包是名字空间和存储路径,另一方面也规定了访问性,比如同一个包中默认情况可互相访问。注:包与继承没有关系,一个superclass只要是public的,子类可以在不同package中继承superclass。
import语句可以导入包,基本语法是:
import package1[.package2...].classname;
例如:import java.util.Date;

作者语:包可以理解为OS里的文件夹。

修饰符

修饰符modifier分为两类:访问修饰符access modifier和其他修饰符。modifer可以修饰类和类的成员(field和method)。

1.访问修饰符

| | 同一个类中 | 同一个包中(包括子类) | 不同包中子类 | 不同包中非子类 |
|:--- :|:-----------:|:----------:|:-------------: |:-------------: |
|private| Yes | | | |
|默认(包可访问)| Yes | Yes | | |
|protected| Yes | Yes | Yes | |
|public| Yes | Yes | Yes| Yes |

private只能在同一个类中访问,可以更好的将信息进行封装和隐藏,存取时使用set和get方法;

public class Person2{
  private int age;
  public void setAge(int age){
    if(age>0 && age <150){
      this.age = age;
    }
  }
  public int getAge(){
    return age;
  }
}

默认是class前面不加修饰符,默认同一个包和类可以访问;
protected只是不允许不同包当中的非子类访问;
public的作用是任何包中都可以调用。

作者语:访问权限由严格到宽松大体流程是,从最严格只能在同一个类中访问的private开始,到同一个包中可以访问的默认修饰,再到宽松一些可以在不同包的子类中调用的protected修饰,最后是最宽松的在任何包中都可以调用的public修饰。

2.其他修饰符

基本含义 修饰类 修饰成员 修饰局部变量
static 静态的、非实例的、类的 可以修饰内部类 Yes
final 最终的、不可改变的 Yes Yes Yes
abstract 抽象的、非实例的 Yes Yes

static字段只属于类,不属于任何对象实例,例如:定义Person类,其中定义一个统计人数的参数,并不属于任何一个对象实例,

class Person{
  static int totalNumber;
  String name;
  int age;
  Person(String n, int a){
    name = n;
    age = a;
  }
}

static方法是属于整个类的方法,不属于某个实例,不能操纵处理某个实例的成员变量;
final修饰的类不能被继承,也就是说不能有子类,final修饰的方法是不能被子类覆盖的方法,final修饰的字段是只读的不能修改;
abstract修饰的类不能实例化,abstract修饰的方法是抽象方法,为所有子类定义统一接口,只需声明,格式如下:

abstarct returnType abstractMethod([paramlist]);

接口

接口interface是某种特征的约定,它也是面向对象编程思想的核心组成部分。

作者语:比如,我们把现实中的飞机写成一个类,其中的战斗机、运输机都是飞机这个类的子类,有自己的特征。战斗机中,歼击机10是歼击机9的新一代,我们说歼击机10继承了歼击机9,在歼击机9的动力系统基础上,歼击机10开发了应急情况另一个加速系统,也就是说有两个动力系统方法,一个是继承歼击机9,另一个是应急下新增加的动力系统,这两个就是多态的应用。
除了飞机外,天空中还有鸟。鸟和飞机两个类都会写一个特征——它们能够离开地面XX米,且有自主控制能力……本着DRY的原则,这里需要优化,接口能很好的解决这个问题,我们可以写一个特征“飞”的接口,飞机和鸟以及其他能飞的物体都可以使用这个接口。

根据接口的定义,它的modifier默认是public+abstarct,因为接口的出现就是要让其他类使用,所以默认是public的;而接口本身就是特征的约定,不是实例化的,所以默认是abstract的。且接口是可以多继承的,与类的继承不一样,甚至有人会说面向对象的编程实质上是“面向接口的变成”,可见接口在面向对象语言中的重要性。

作者语:Java规定类是单继承,而接口在某种程度上说可以打破这个限制,接口不关注类之间的层次,可以直接使用某个特征方法函数。

接口的定义一般如下:

[public] interface InterfaceName [extends listOfSuperInterface]{
  returnType methodName([paramlist]);
}

如果定义中没有public声明,则只能被同一个包中的类访问;
extends继承部分与类的继承语法一致,不同的是接口可以多重继承,用逗号隔开即可;
接口中只进行方法的声明,不提供具体实现,所以只有方法体,用“;”结束,这里的方法具有public和abstract属性。
接口的实现用implements子句

class className implements interfaceName{
  returnType methodName([paramlist]){
    //写接口中所声明方法的实现
  }
}

接口中定义的常量具有public, static, final的属性,一般大写名字:

type NAME = value;

下面的代码用接口定义了人

interface Runner(){public void run();}
interface Swimmer(){public void swim();}
interface Flyable(){
  abstract public void fly();
  public void land();
  public void takeoff();
}
abstract class Animal{
  int age;
  abstract public void eat();
}
class Person extends Animal implements Runner, Swimmer, Flyable{
  public void run(){System.out.println("run");}
  public void swim(){System.out.println("swim");}
  public void fly(){System.out.println("fly");}
  public void land(){System.out.println("land");}
  public void takeoff(){System.out.println("takeoff");}
  public void eat(){System.out.println("eat");}
}
public class Test{
  public static void main(String[] args){
    Test t = new Test();
    Person p =  new Person();
    t.m1(p);
    t.m2(p);
    t.m3(p);
    t.m4(p);
  }
  public void m1(Runner r){r.run();}
  public void m2(Swimmer s){s.swim();}
  public void m3(Flyable f){f.fly(); f.land(); f.takeoff();}
  public void m4(Animal a){a.eat();}
}

To be continued

Java完整的源文件格式如下:

package packageName//指定文件中的类所在的包,0/1个
import packageName.[className]; //指定引入的类,0/多个
public class classDefinition //属性为public的类定义,0/1个,名字必须与文件名一致
{
  [public] interface InterfaceName [extends listOfSuperInterface]//接口的定义
  {
    type constantName = value; //接口常量声明,默认是public, static, final的
    returnType methodName([paramlist]); //接口方法声明,没有方法体
  }
  [public] [abstract|final] class className [extends superClassName] [implements InterfaceNameList] //类的声明
  {
    [public|protected|private] [static] [final] type variableName; //成员变量声明
    [public|protected|private] [static] [final] returnType methodName([paramlist]) [throws exceptionlist] //方法声明及实现
    {
      statement;
    }
  }
}

有三种方法要求固定的声明方式:

  • 构造方法
className([paramlist]){
  statements;
}
  • main方法
public static void main(String[] args){
  statements;
}
  • finalize方法
protected void finalize() throw throwable{
  statements;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,500评论 18 399
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,198评论 0 2
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,607评论 0 11
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,030评论 0 62
  • 转自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帅199207阅读 8,474评论 3 93