包的本质就是文件夹
作用:
声明包的语法格式
package 包名;
使用包的规则和规范
如何跨包使用类
前提:被使用的类或成员的权限修饰符是>缺省的,即可见的
概述
static是一个静态修饰符关键字,表示静态的意思,可以修饰成员变量和成员方法以及代码块。
static修饰成员变量
当 static
修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。定义格式:
静态成员变量的访问方式:
代码示例
public class Person {
// 非静态变量
String name;// 姓名
// 静态变量
static String country;// 国籍
// 构造方法
public Person() {
}
public Person(String name, String country) {
this.name = name;
this.country = country;
}
}
public class Test {
public static void main(String[] args) {
// 创建Person对象
Person p1 = new Person("张三", "中国");
System.out.println(p1.name+","+p1.country);// 张三,中国
System.out.println("=======================");
// 创建Person对象
Person p2 = new Person();
// 没有使用static修饰country
// System.out.println(p2.name+","+p2.country);// null,null
// 使用static修饰country
System.out.println(p2.name+","+p2.country);// null,中国
System.out.println("=======================");
System.out.println(Person.country);// 中国
}
}
static修饰成员方法
概述
被static修饰的方法会变成静态方法,也称为类方法,该静态方法可以使用类名直接调用。
代码示例
public class Person {
// 非静态方法
public void method1(){
System.out.println("Person method1...");
}
// 静态方法
public static void method2(){
System.out.println("Person method2...");
}
}
public class Test {
public static void main(String[] args) {
/*
static修饰成员方法:
格式:修饰符 static 返回值类型 方法名(形参列表){方法体}
特点:被static修饰的成员方法叫做静态成员方法
使用:
对象名.静态成员方法名(实参);
类名.静态成员方法名(实参); ----->推荐
*/
Person p = new Person();
p.method2();
// 类名.静态成员方法名(实参);
Person.method2();
}
}
静态方法调用的注意事项:
以后开发中static的应用
static修饰代码块
static {
System.out.println("静态代码块");
}
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成某种关系。如图所示:
多个类可以称为子类,也叫派生类;多个类抽取出来的这个类称为父类、超类(superclass)或者基类。继承描述的是事物之间的所属关系,这种关系是:is-a
的关系。例如,图中猫属于动物,狗也属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。
继承的好处
继承的格式
通过 extends
关键字,可以声明一个子类继承另外一个父类,定义格式如下:
代码示例
/*
* 定义动物类Animal,做为父类
*/
class Animal {
// 定义name属性
String name;
// 定义age属性
int age;
// 定义动物的吃东西方法
public void eat() {
System.out.println(age + "岁的" + name + "在吃东西");
}
}
/*
* 定义猫类Cat 继承 动物类Animal
*/
class Cat extends Animal {
// 定义一个猫抓老鼠的方法catchMouse
public void catchMouse() {
System.out.println("抓老鼠");
}
}
/*
* 定义测试类
*/
public class ExtendDemo01 {
public static void main(String[] args) {
// 创建一个猫类对象
Cat cat = new Cat();
// 为该猫类对象的name属性进行赋值
cat.name = "Tom";
// 为该猫类对象的age属性进行赋值
cat.age = 2;
// 调用该猫的catchMouse()方法
cat.catchMouse();
// 调用该猫继承来的eat()方法
cat.eat();
}
}
继承后构造方法的访问规则
如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
继承后非私有成员的访问规则
继承后私有成员的访问规则
继承的特点
Java只支持单继承,不支持多继承。
//一个类只能有一个父类,不可以有多个父类。
class C extends A{} //ok
class C extends A,B... //error
Java支持多层继承(继承体系)。
class A{}
class B extends A{}
class C extends B{}
顶层父类是Object类。所有的类默认继承Object,作为父类。
子类和父类是一种相对的概念。例如:B类对于A来说是子类,但是对于C类来说是父类
一个父类可以同时拥有多个子类
方法重写
我们说父类的所有方法子类都会继承,但是当某个方法被继承到子类之后,子类觉得父类原来的实现不适合于子类,该怎么办呢?我们可以进行方法重写 (Override)。子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
class Phone {
public void sendMessage(){
System.out.println("发短信");
}
public void call(){
System.out.println("打电话");
}
public void showNum(){
System.out.println("来电显示号码");
}
}
//智能手机类
class NewPhone extends Phone {
//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能
public void showNum(){
//调用父类已经存在的功能使用super
super.showNum();
//增加自己特有显示姓名和图片功能
System.out.println("显示来电姓名");
System.out.println("显示头像");
}
}
public class ExtendsDemo06 {
public static void main(String[] args) {
// 创建子类对象
NewPhone np = new NewPhone();
// 调用父类继承而来的方法
np.call();
// 调用子类重写的方法
np.showNum();
}
}
重写的注意事项
this关键字的三种用法
this访问本类成员变量: this.成员变量
public class Student{
String name = "张三";
public void show(){
String name = "李四";
System.out.println("name = " + name);// 李四
System.out.println("name = " + this.name);// 张三
}
}
this访问本类成员方法: this.成员方法名();
public class Student{
public void show(){
System.out.println("show方法...");
this.eat();
}
public void eat(){
System.out.println("eat方法...");
}
}
this访问本类构造方法: this( )可以在本类的一个构造方法中,调用另一个构造方法
public class Student{
public Student(){
System.out.println("空参构造方法...");
}
public Student(String name) {
this();//当使用this()调用另一个构造方法时,此代码必须是此构造方法的第一句有效代码。
System.out.println("有参构造方法...");
}
}
public class Demo {
public static void main(String[] args) {
Student stu2 = new Student();
}
}
super关键字的三种用法
super访问父类的成员变量: super.父类成员变量名
class Fu{
int num = 100;
}
class Zi extends Fu{
int num = 10;
public void show(){
int num = 1;
System.out.println("局部变量num:"+num);// 1
System.out.println("Zi 类中的num:"+this.num);// 10
System.out.println("Fu 类中的num:"+super.num);// 100
}
}
super访问父类的成员方法: super.成员方法名();
class Fu{
public void method1(){
System.out.println("Fu method1...");
}
}
class Zi extends Fu{
public void show(){
// 访问父类的method1方法
super.method1();
}
@Override
public void method1(){
super.method1();// 调用父类的method1方法
System.out.println("Zi method1...");
}
}
super访问父类的构造方法: super( )
class Fu {
public Fu() {
System.out.println("Fu 类的空参构造方法..");
}
public Fu(String name, int age) {
System.out.println("Fu 类的有参构造方法..");
}
}
class Zi extends Fu {
public Zi() {
super();// 调用父类的空参构造方法
System.out.println("Zi 类的空参构造方法..");
}
public Zi(String name, int age) {
super(name, age);// 调用父类的有参构造方法
System.out.println("Zi 类的有参构造方法..");
}
}
public class Demo {
public static void main(String[] args) {
Zi zi = new Zi();
System.out.println("----------------------");
Zi z2 = new Zi("刘德华", 17);
}
}
注意事项
使用abstract关键字修饰的类就是抽象类。这种类不能被创建对象,它就是用来做父类的,被子类继承的。
语法:
抽象方法的概述
语法:
作用: 强制要求子类重写的方法可以定义为抽象方法
代码示例
abstract class Animal {
// 成员变量
private String name;
private int age;
// 构造方法
public Animal(){
}
public Animal(String name, int age){
this.name = name;
this.age = age;
}
// 成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 所有子类显示信息的方法实现都是一样的
public void show(){
System.out.println(name+","+age);
}
// 抽象方法 ---
// 因为所有子类吃东西的方法实现不一样
public abstract void eat();
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头...");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼...");
}
}
public class Test {
public static void main(String[] args) {
/*
抽象方法:
概述: 使用abstract修饰,并且没有方法体的方法
格式: 修饰符 abstract 返回值类型 方法名(形参列表);
抽象方法的使用场景:如果父类中某个方法,所有子类都有不同的实现,那么就可以把该方法定义为抽象方法
抽象方法的作用: 强制要求子类重写
*/
Dog d = new Dog();
d.eat();
Cat c = new Cat();
c.eat();
}
}
抽象类的注意事项
关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。
抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。
理解:子类的构造方法中,有默认的super()或手动的super(实参列表),需要访问父类构造方法。
抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。
抽象类体现的就是模板设计思想
模板模式的实现步骤
代码示例
// 父类
abstract class Driver {
// 开车方法 通用模板
public void driveCar() {
System.out.println("开门");
System.out.println("点火");
// 姿势??
ziShi();
System.out.println("刹车");
System.out.println("熄火");
}
// 姿势方法 填充模板
public abstract void ziShi();
}
//现在定义两个使用模板的司机:
//新司机
class NewDriver extends Driver {
@Override
public void ziShi() {
System.out.println("双手紧握方向盘");
}
}
//老司机
class OldDriver extends Driver {
@Override
public void ziShi() {
System.out.println("右手握方向盘左手抽烟");
}
}
public class Test {
public static void main(String[] args) {
// 创建新司机对象
NewDriver d1 = new NewDriver();
d1.driveCar();
// 创建老司机对象
OldDriver d2 = new OldDriver();
d2.driveCar();
}
}
可以看出,模板模式的优势是,模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!非常的强大!
概述: final关键字表示不可改变。可以用于修饰类、方法和变量。
修饰类:表示这个类不能被继承,没有子类
查询API发现像 public final class String
、public final class Math
、public final class Scanner
等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。
代码示例
final class Eunuch{//太监类
}
class Son extends Eunuch{//错误
}
修饰方法:表示这个方法不能被子类重写
代码示例
class Father{
public final void method(){
System.out.println("father");
}
}
class Son extends Father{
public void method(){//错误
System.out.println("son");
}
}
修饰变量
基本类型的局部变量:被final修饰后,只能赋值一次,不能再更改。代码如下:
public class FinalDemo1 {
public static void main(String[] args) {
// final修饰基本数据类型
final int NUM = 10;
// NUM = 20;// 编译报错,final修饰的变量只能赋值一次,不能重复赋值
}
}
引用类型的局部变量:被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改,代码如下:
public class FinalDemo2 {
public static void main(String[] args) {
// 引用类型
final Student stu = new Student("张三", 18);
//stu = new Student("李四",19);// 编译报错
stu.setAge(19);
}
}
成员变量
成员变量涉及到初始化的问题,初始化方式有两种,只能二选一:
显示初始化;
public class FinalVariable {
final int NUM1 = 10;
}
构造方法初始化
public class FinalVariable {
final int NUM2;
public FinalVariable(int NUM2) {
this.NUM2 = NUM2;
}
public FinalVariable() {
this.NUM2 = 10;
}
}
被final修饰的常量名称,一般都有书写规范,所有字母都大写。