Java基础——面向对象编程高级(常见关键字)

package:用于声明一个类或接口所属的包(即命名空间)

语法格式:

package 顶层包名.子包名

OrderController类属于包com.hxzs.order.controller

  • 一个源文件只能有一个声明包的package语句
  • package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。
  • 包名,属于标识符,满足标识符命名的规则和规范(全部小写)、见名知意
    • 包通常使用所在公司域名的倒置:com.gongsi.xxx。
    • 大家取包名时不要使用"java.xx"包
  • 包对应于文件系统的目录,package语句中用 “.” 来指明包(目录)的层次,每.一次就表示一层文件目录。
  • 同一个包下可以声明多个结构(类、接口),但是不能定义同名的结构(类、接口)。不同的包下可以定义同名的结构(类、接口)

作用:

  • 包可以包含类和子包,划分项目层次,便于管理
  • 帮助管理大型软件系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
  • 解决类命名冲突的问题
  • 控制访问权限

举例:MVC设计模式

MVC是一种软件构件模式,目的是为了降低程序开发中代码业务的耦合度。MVC设计模式将整个程序分为三个层次:视图模型(Viewer)层,控制器(Controller)层,与数据模型(Model)层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式使程序结构变的灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程序的耦合性。

视图层viewer:显示数据,为用户提供使用界面,与用户直接进行交互。
 >相关工具类   view.utils
 >自定义view  view.ui

控制层controller:解析用户请求,处理业务逻辑,给予用户响应
 >应用界面相关    controller.activity
 >存放fragment   controller.fragment
 >显示列表的适配器 controller.adapter
 >服务相关的        controller.service
 >抽取的基类        controller.base
   
模型层model:主要承载数据、处理数据
 >数据对象封装 model.bean/domain
 >数据库操作类 model.dao
 >数据库      model.db

常见包:

java.lang----包含一些Java语言的核心类,如String、Math、Integer、 System和Thread,提供常用功能。

 java.net----包含执行与网络相关的操作的类和接口。

java.io ----包含能提供多种输入/输出功能的类。

java.util----包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。

java.text----包含了一些java格式化相关的类

java.sql----包含了java进行JDBC数据库编程的相关类/接口

java.awt----包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

import:用于导入其他包中的类或接口。

语法格式:

import 包名.类名;

标红:

  • import语句,声明在包的声明和类的声明之间。
  • 如果需要导入多个类或接口,那么就并列显式多个import语句即可
  • 如果使用a.*导入结构,表示可以导入a包下的所有的结构。举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
  • 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
  • 如果已经导入java.a包下的类,那么如果需要使用a包的子包下的类的话,仍然需要导入。
  • 如果在代码中使用不同包下的同名的类,那么就需要使用类的全类名的方式指明调用的是哪个类。
  • (了解)import static组合的使用:调用指定类或接口下的静态的属性或方法

this:指代当前对象实例的引用。

是什么:

this关键字不算难理解,它的作用和其词义很接近。

    • 它在方法(准确的说是实例方法或非static的方法)内部使用,表示调用该方法的对象
    • 它在构造器内部使用,表示该构造器正在初始化的对象。

this可以调用的结构:成员变量、方法和构造器

什么时候用:

①实例方法或构造器中使用当前对象的成员

在实例方法或构造器中,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的可读性。不过,通常我们都习惯省略this

但是,当形参与成员变量同名时,如果在方法内或构造器内需要使用成员变量,必须添加this来表明该变量是类的成员变量。即:我们可以用this来区分成员变量局部变量比如:

另外,使用this访问属性和方法时,如果在本类中未找到,会从父类中查找。

②同一个类中构造器互相调用

this可以作为一个类中构造器相互调用的特殊格式。

this():调用本类的无参构造器

this(实参列表):调用本类的有参构造器

标红:

  • 不能出现递归调用。比如,调用自身构造器。
    • 推论:如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(形参列表)"
  • this()和this(实参列表)只能声明在构造器首行。
    • 推论:在类的一个构造器中,最多只能声明一个"this(参数列表)"

super:指代当前对象的父类或父接口。

理解:

使用super来调用父类中的指定操作:

  • super可用于访问父类中定义的属性
  • super可用于调用父类中定义的成员方法
  • super可用于在子类构造器中调用父类的构造器
  • 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
  • super的追溯不仅限于直接父类
  • super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

使用:

①子类中调用父类被重写的方法
  • 如果子类没有重写父类的方法,只要权限修饰符允许,在子类中完全可以直接调用父类的方法;
  • 如果子类重写了父类的方法,在子类中需要通过super.才能调用父类被重写的方法,否则默认调用的子类重写的方法

方法前面没有super.和this.

  • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯

方法前面有this.

  • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯

方法前面有super.

  • 从当前子类的直接父类找,如果没有,继续往上追溯
②子类中调用父类中同名的成员变量
  • 如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
  • 如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
  • 如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问

总结:起点不同(就近原则)

变量前面没有super.和this.

    • 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量
    • 如果不是局部变量,先从当前执行代码的本类去找成员变量
    • 如果从当前执行代码的本类中没有找到,会往上找父类声明的成员变量(权限修饰符允许在子类中访问的)

变量前面有this.

    • 通过this找成员变量时,先从当前执行代码的==本类去找成员变量==
    • 如果从当前执行代码的本类中没有找到,会往上找==父类声明的成员变量(==权限修饰符允许在子类中访问的)

变量前面super.

    • 通过super找成员变量,直接从当前执行代码的直接父类去找成员变量(权限修饰符允许在子类中访问的)
    • 如果直接父类没有,就去父类的父类中找(权限修饰符允许在子类中访问的)

特别说明:应该避免子类声明和父类重名的成员变量(阿里开发手册

③子类构造器中调用父类构造器

① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。

② 规定:“super(形参列表)”,必须声明在构造器的首行。

③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,  结合②,结论:在构造器的首行,"this(形参列表)" 和 "super(形参列表)"只能二选一。

④ 如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用"super(形参列表)",  则子类此构造器默认调用"super()",即调用父类中空参的构造器。

⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。  只能是这两种情况之一。

⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)",则剩下的那个一定使用"super(形参列表)"。

开发中常见错误:如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有空参的构造器,则编译出错

static:表示一个成员(变量或方法)属于类本身,而不是类的实例。

类属性、类方法设计思想

当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份。例如,所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。此外,在类中声明的实例方法,在类的外面必须要先创建对象,才能调用。但是有些方法的调用者和当前类的对象无关,这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。这里的类变量、类方法,只需要使用static修饰即可。所以也称为静态变量、静态方法。

static

  • 使用范围:
    • 在Java类中,可用static修饰属性、方法、代码块、内部类
  • 被修饰后的成员具备以下特点:
    • 随着类的加载而加载
    • 优先于对象存在
    • 修饰的成员,被所有对象所共享
    • 访问权限允许时,可不创建对象,直接被类调用

静态变量

语法格式:

使用static修饰的成员变量就是静态变量(或类变量、类属性)

[修饰符] class{
    [其他修饰符] static 数据类型 变量名;
}

 特点:
  • 静态变量的默认值规则和实例变量一样。
  • 静态变量值是所有对象共享。
  • 静态变量在本类中,可以在任意方法、代码块、构造器中直接使用。
  • 如果权限修饰符允许,在其他类中可以通过“类名.静态变量”直接访问,也可以通过“对象.静态变量”的方式访问(但是更推荐使用类名.静态变量的方式)。
  • 静态变量的get/set方法也静态的,当局部变量与静态变量重名时,使用“类名.静态变量”进行区分。

静态方法

语法格式:

用static修饰的成员方法就是静态方法。

[修饰符] class{
    [其他修饰符] static 返回值类型 方法名(形参列表){
        方法体
    }
}

特点:
  • 静态方法在本类的任意方法、代码块、构造器中都可以直接被调用。
  • 只要权限修饰符允许,静态方法在其他类中可以通过“类名.静态方法“的方式调用。也可以通过”对象.静态方法“的方式调用(但是更推荐使用类名.静态方法的方式)。
  • 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
  • 静态方法可以被子类继承,但不能被子类重写。
  • 静态方法的调用都只看编译时类型。
  • 因为不需要实例就可以访问static方法,因此static方法内部不能有this,也不能有super。如果有重名问题,使用“类名.”进行区别。

final:表示一个变量的值不能被修改(对于变量),或者一个类不能被继承(对于类),或者一个方法不能被覆盖(对于方法)。

理解:最终的、不可更改的

使用:

①final修饰类

表示这个类不能被继承,没有子类。提高安全性,提高程序的可读性。

例如:String类、System类、StringBuffer类

final class Eunuch{//太监类
   
}
class Son extends Eunuch{//错误
   
}

②final修饰方法

表示这个方法不能被子类重写。

例如:Object类中的getClass()

class Father{
    public final void method(){
       System.out.println("father");
    }
}
class Son extends Father{
    public void method(){//错误
       System.out.println("son");
    }
}

③final修饰变量

final修饰某个变量(成员变量或局部变量),一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。

例如:final double MY_PI = 3.14;

如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)

  • 修饰成员变量

public final class Test {
    public static int totalNumber = 5;
    public final int ID;

    public Test() {
        ID = ++totalNumber; // 可在构造器中给final修饰的“变量”赋值
    }
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.ID);
    }
}

  • 修饰局部变量:

public class TestFinal {
    public static void main(String[] args){
        final int MIN_SCORE ;
        MIN_SCORE = 0;
        final int MAX_SCORE = 100;
        MAX_SCORE = 200; //非法
    }
}

abstract:表示一个类或方法没有具体的实现(对于类),或者一个方法没有具体的实现(对于方法)。

由来:

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

我们声明一些几何图形类:圆、矩形、三角形类等,发现这些类都有共同特征:求面积、求周长。那么这些共同特征应该抽取到一个共同父类:几何图形类中。但是这些方法在父类中又无法给出具体的实现,而是应该交给子类各自具体实现。那么父类在声明这些方法时,就只有方法签名,没有方法体,我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类必须是抽象类

语法格式:

抽象类:被abstract修饰的类。

[权限修饰符] abstract class 类名{
}
[权限修饰符] abstract class 类名 extends 父类{   
}

抽象方法:被abstract修饰没有方法体的方法。也就是说抽象方法没有方法体,因为它抽象啊,要是有方法体它就不抽象了

[其他修饰符] abstract 返回值类型 方法名([形参列表]);

使用:

  • 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  • 抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
  • 抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。

理解:子类的构造方法中,有默认的super()或手动的super(实参列表),需要访问父类构造方法。

  • 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

标红:

  • 不能用abstract修饰变量、代码块、构造器;
  • 不能用abstract修饰私有方法、静态方法、final的方法、final的类。

举例: 模板设计模式

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

解决的问题

  • 当功能内部一部分实现是确定的,另一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
  • 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。

🤣英语作文模板🤣

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值