1 Java类与对象
1.1 类
- 属性:类的
成员变量
,作用范围是整个类,有默认值。 - 功能:类的
成员方法
。
一般成员变量设为private
, 成员方法为public
.修饰符 class 类名{ //成员变量定义 修饰符 数据类型 变量名[ = 值] ; //成员方法定义 修饰符 返回值类型 方法名(参数列表){ ... //方法内容 } }
- 构造方法
修饰符 构造方法名(参数列表){ ... //构造方法实体 }
- 构造方法注意事项
- 构造方法没有返回值类型和返回值。
- 构造方法名和类名相同。
- 构造方法在创建对象的时候执行一次,未自己定义构造方法时编译器会创建一个默认构造方法,自己定义了则编译器不会创建默认构造方法。
- 构造方法可以重载。
- 构造方法注意事项
static
关键字- static修饰类中的成员,该成员属于该类,不属于该类的某个对象。(对象的共享数据)
- 成员调用:
类名.成员
,也可以使用对象.成员
- static注意事项:
- 静态不能调用非静态。原因:静态内容先于对象存在内存中,只能访问静态,不能用this/super。
但是可以创建对象来调用非静态方法。public class Fu { public static int a = 1; public static void show() { System.out.println("This is superclass!!"); ceshi(); //编译错误,静态不能调用非静态,而且这里不能使用 this.ceshi(); //但是可以创建一个对象来调用非静态方法 Fu f = new Fu(); f.ceshi(); } public void ceshi() { System.out.println("xixix"); } }
- 技巧:方法中未用到非静态成员,推荐使用static修饰该方法。
- 静态不能调用非静态。原因:静态内容先于对象存在内存中,只能访问静态,不能用this/super。
1.2 对象
对象是类的实例。
- 创建对象:
类名 对象名 = new 构造方法(参数列表);
- 匿名对象:没有引用变量,只能使用一次。
new 构造方法(参数列表)
1.3 内部类
- 类写在其他类内部,作为成员内部类或局部内部类。
public class Outer{ //成员内部类 public class Inner{ public void show(){ System.out.println("This is an inner class!!"); } } }
- 非静态内部类不能有静态成员。
原因:JVM加载顺序:类 → \rightarrow →静态成员 → \rightarrow →类对象,要求静态变量在对象创建之前完成, - 创建内部类引用对象:
外部类名.内部类名 变量 = 外部类对象.new 内部类构造方法(参数列表)
.Outer.Inner in = new Outer().new Inner(); in.show(); //调用内部类方法
- 在内部类中对内部类与外部类同名成员调用:
- 内部类成员:
this.成员
- 外部类成员:
外部类名.this.成员
package org.ywq.innerclass; public class Outer { private int a=1; //成员内部类 public class Inner{ private int a=2; public void inner() { int a=3; System.out.println(a); //output 3 System.out.println(this.a); //output 2 System.out.println(Outer.this.a); //output 1 } } }
- 内部类成员:
2 面向对象三大特征
2.1 封装
- 隐藏实现细节,对外提供可以访问的方式。
- 方法、类、包都是封装。
- 封装要求将成员变量设为private, 所以要添加
set变量名()
,get变量名()
成员方法对成员变量进行间接访问。(private成员只能在本类中使用)public class Person{ private String name; private int age; //set方法 public void setName(String name){ this.name=name; } public void setAge(int age){ this.age=age; } //get方法 public String getName(){ return name; } public int getAge(){ return age; } }
this
关键字- this表示本类对象的引用、调用方法的对象,在类中可以省略不写
(强烈不建议)
。 - 通过this可区分类中成员变量和局部变量同名。
this()
用法:调用本类的构造方法。(该语句必须是构造方法中第一个statement)class Person{ protected String name; protected int age; //default constructor public Person(){ this("Lili",1); //调用重载的构造方法Person(String name, int age) } //Overload constructor public Person(String name, int age){ this.name=name; this.age=age; } }
- this表示本类对象的引用、调用方法的对象,在类中可以省略不写
2.2 继承
子类拥有父类所有可继承的变量和方法。
-
格式(
extends
关键字)class 子类 extends 父类{ .... }
-
继承的注意事项
- Java
不允许多继承
:一个类只能继承一个父类。
原因:可能有安全隐患,如两个类中有相同的方法。class A extends B,C{} //错误,不被允许
- Java
支持多重继承
:B类继承A类,C类继承B类。class A{} class B extends A{} class C extends B{}
- Java
-
方法重写(Override)
-
子类中对父类的方法进行重写(方法名和参数列表保持一致)。
-
主要目的是保持父类功能,并添加子类的新功能。
class Son extends Father{ @Override public void showTelephone(){ super.showTelephone(); //父类的功能 System.out.println("New Function!!"); //添加子类的新功能 }
[特殊重写方式1]——通过匿名对象重写方法(仅临时有效)
public class Test{ public static void main(String[] args) { //Way 1: Son son = new son(){ //Override public void showTelephone(){ ... //添加重写方法体,仅临时有效 } }; son.showTelephone(); //Way 2: new son(){ //Override public void showTelephone(){ ... //添加重写方法体,仅临时有效 } }.showTelephone(); } }
[特殊重写方式2]——
Lamba表达式
(Java8新特性)- Lambda表达式相当于一个匿名方法,主要用来代替匿名对象方法重写的繁琐语法(也是创建一个对象实例)。
- Lambda表达式组成:
- 形参列表;(允许省略形参类型)
- 箭头(->)
- 代码块。
- Java中Lambda表达式的目标类型必须是函数式接口——只有一个抽象方法的接口,但可以多个非抽象方法。
package org.ywq.lambda; interface Eatable { void taste(); } interface Flyable { void fly(String weather); } interface Addable { int add(int a, int b); } public class Test { public void eat(Eatable e) { System.out.println(e); e.taste(); } public void drive(Flyable f) { System.out.println("我正在驾驶: " + f); f.fly("[大晴天]"); } public void addTest(Addable add) { System.out.println("5和3的和为: " + add.add(5, 3)); } public static void main(String[] args) { Test la = new Test(); //创建了Eatable接口实例,重写taste()方法,代码块只有1条语句,可省略花括号和分号 la.eat(() -> System.out.println("真香!!")); // 创建了Flyable接口实例,重写fly(String weather)方法,参数列表只有一个形参可以省略圆括号 la.drive(weather -> { System.out.println("今天天气是:" + weather); System.out.println("飞机飞行正常!!!"); } ); // 创建了Addable接口实例,重写add(int a, int b)方法,代码块只有1条语句,省略花括号,也可省略return la.addTest((a, b) -> a + b); } }
-
注意:重写时子类方法权限要大于等于父类方法权限
class father{ public void show(){ } } class son extends father{ void show(){ //default权限 < public权限,编译失败 } }
四大权限:
public
>protected
>private
.
技巧:所有方法权限都设置为public.
权限修饰符可以用来修饰类、类的成员变量、类的成员方法。
-
权限 | public | protected | private |
---|---|---|---|
本类 | Y | Y | Y |
本包中的类 Package | Y | Y | |
外部包中的类 World | Y |
super
关键字- 父类英文为superclass
- super指父类的存储空间,可以理解为父类的引用对象。
super()
用法:调用父类的构造方法,完成父类成员的初始化操作。- 子类的构造方法第一行都有默认的隐式
super();
语句,除非是第一行使用this(参数列表);
语句。 super();
可以替换成手动写的super(参数列表);
调用父类的相应构造方法。
- 子类的构造方法第一行都有默认的隐式
2.3 多态
-
表现:父类引用变量可以指向子类对象。(接口与实现类也满足)
-
自动类型转化。
父类 引用变量名 = new 子类();
-
多态规则:
- 成员变量
编译、运行全看父类。 - 成员方法
编译看父类,非静态成员方法运行先看子类(重写方法),子类未重写再看父类。
静态成员方法运行也看父类。(多态针对对象,而静态成员与对象无关)
注:如果是子类特有方法,需要强制类型转换才能调用。
- 成员变量
-
多态作用
在方法的参数列表中,可以使用父类数据类型,引用变量调用方法时参数可以是各个子类对象。
如:/******************接口 USB.java****************************/ /* *如果对接口不熟悉,可以参见本文 第4部分接口 内容 */ package org.ywq.duotai; public interface USB { public abstract void open(); public abstract void close(); }
/******************鼠标 Mouse.java****************************/ package org.ywq.duotai; public class Mouse implements USB{ @Override public void open() { System.out.println("打开鼠标"); } @Override public void close() { System.out.println("关闭鼠标"); } }
/******************键盘 Keyboard.java****************************/ package org.ywq.duotai; public class Keyboard implements USB{ @Override public void open() { System.out.println("打开键盘"); } @Override public void close() { System.out.println("关闭键盘"); } }
/******************电脑 Computer.java****************************/ package org.ywq.duotai; public class Computer { public static void open() { System.out.println("打开电脑"); } public static void close() { System.out.println("关闭电脑"); } //使用USB设备 public void useUSB(USB usb) { //成员方法参数类型为USB接口类型,可以用Mouse和Keyboard引用变量 usb.open(); usb.close(); } }
/******************测试 Test.java****************************/ package org.ywq.duotai; public class Test { public static void main(String[] args) { Computer computer=new Computer(); computer.useUSB(new Mouse()); computer.useUSB(new Keyboard()); } }
-
instanceof
关键字- 用于判断对象是否属于某种数据类型。
对象 instanceof 数据类型 //返回 true 或 false
注意:数据类型为类时,
对象 instanceof 父类
为true.
如任意创建的类都是Object类的子类,所以对象 instanceof Object
始终是true. - 用于判断对象是否属于某种数据类型。
3 抽象类
-
使用
abstract
关键字。 -
定义抽象类
public abstract class Develop { public abstract void work(); }
-
抽象类作用:定义没有方法体的方法,子类继承抽象类并强制重写抽象方法。
public class JavaEE extends Develop { @Override public void work() { System.out.println("JavaEE工程师在工作!"); } }
-
注意:
- 抽象类不能实例化对象。
- 如果子类继承抽象类并只重写了一部分抽象方法,则该子类还是抽象类。
- 抽象类中可以没有抽象方法。
-
final
关键字- final意思是最终,不可变的。
- final可以修饰类、类的成员和局部变量。
- final修饰的类不能被继承,但可以继承其他类。
public final class Zi extends Fu{ }
- final修饰的方法不能被重写(Override)
- final修饰的基本数据类型变量称为常量,只能被赋值一次。
final int a = 1;
- final修饰的引用变量,保持内存地址不变。
final Fu fu = new Zi(); fu = new Zi(); //编译错误,final引用变量地址不能改变。
- final修饰的类不能被继承,但可以继承其他类。
4 接口
- 接口是功能的集合,是比抽象类更抽象的类,使用
interface
关键字。 - 接口只描述应该具备的方法,没有具体实现。(接口内方法全是抽象方法)
- 接口中成员变量必须为常量。
- 接口定义:
MyInterfaceDemo.class
文件:public interface MyInterfaceDemo{ //定义常量 public static final 数据类型 变量名 = 值; //定义抽象方法 public abstract 返回值类型 方法名(参数列表); }
- 接口实现(
implements
关键字)——接口和实现类public class 类 implements 接口{ 重写接口中的抽象方法; }
- 接口注意事项
- 接口
允许多实现
:实现多个接口。
原因:接口中都是抽象方法,没有安全隐患。public class C implements A,B{}
- 类可以继承superclass同时实现接口
public class D extends C implements A,B{}
- 接口可以继承接口,且支持多继承。
public interface C extends A,B{}
- 接口
- 接口和抽象类的区别
- 抽象类是事物都具备的内容(共性),继承体系是
is..a关系
。 - 接口是事物额外内容(特性),继承体系是
like..a关系
。
- 抽象类是事物都具备的内容(共性),继承体系是
5 包Package
- 包就是文件夹,存放类文件,一般将相同功能的类放到一个包中。
- 类中包的声明格式(在class文件最开头):
package 包名.包名.包名...;
- 导入包:
import 包名.包名...包名.类名;