目录
1、概念简介
面向对象认为客观世界是由对象组成的,对象由类(属性和方法)组成,对象可按其属性进行分类,对象之间的联系通过传递消息来实现,对象具有封装性、继承性和多态性。即:将功能封装进对象,强调了对象的功能。
2、面向对象和面向过程的区别
面向过程
:把系统划分为多个功能模块,功能和数据是分开的;
面向对象
:把系统划分多个对象,功能和数据封装到一个对象中,所有对数据的操作封装的对象中;
3、类与对象
3.1、类
(1)类的组成:属性(对象具体特征,如:姓名)和方法(对象的行为,如:跑步)
(2)语法:[权限修饰符] class 类名{
属性声明;
方法声明;
}
(3)实现步骤:
<1、定义类,类名首字母大写;
<2、编写类的属性(考虑修饰符、属性类型、属性名、初始化值)
< 3、编写类的方法(考虑修饰符、返回值类型、方法名、形参等)
public class Person {
String name;//属性
int age; //属性
//打印名字
public void name() {
//方法1
System.out.println("名字:"+name);
}
/**
* 获取年龄
* @return
*/
public int age() {
//方法2
return age;
}
}
3.2、对象:
(1)作用:类的实例化,创建类的对象;
(2)特点:每个类可创建多个对象,且每个对象之间互不干扰;
(3)语法:类名 实例化对象名=new 构造器 如:Person person= new Person();
new 构造器.方法(匿名对象) 如: new Person().shout();
注意:当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。
Person person= new Person();//实例化对象,创建类的对象
person.name="小明";
person.age=12;
person.name();
4、类的成员
属性(变量)
(1)定义:描述对象的特点(如:名字,年龄)
(2)语法:修饰符 类型 属性名=初值;
(3)分类:
(4)成员变量与局部变量区别
成员变量:
-
成员变量定义在类中,在整个类中都可以被访问。
-
成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存中。
-
成员变量有默认初始化值。
-
成员变量的权限修饰符可以根据需要,选择任意一个
局部变量:
- 局部变量只定义在局部范围内,如:方法内,代码块内等
- 局部变量存在于栈内存中。
- 作用的范围结束,变量空间会自动释放。
- 局部变量没有默认初始化值,每次必须显式初始化。
- 局部变量声明时不指定权限修饰符
案例:
public class Animal {
{
int w=23; //代码快局部变量
}
private String ears;//private 定一的只有在本类中的方法访问
public String name;//public 声明属性可以被类以外的其他方法访问
public int age; //成员变量 实例变量
int leg;
static int ear; //成员变量 类变量 以static修饰
/**
* 方法:吃
* @param food
*/
public void eat(String food) {
//局部变量 形参
int a=21;//局部变量 方法局部变量
System.out.println("吃的:"+food);
}
public void goOut(String movetype) {
System.out.println("出行方式:"+movetype);
}
}
方法
(1)定义:描述对象的行为动作(如:吃饭)
(2)特征:每个类可创建多个方法;(方法名第二个首字母大写)
(3)语法:修饰符 返回值类型 方法名(参数列表){方法体}
(4)分类:
有返回值: public 返回值类型(int) name([参数]){ //返回值类型修饰有返回值
return 返回值(参数); }
没有返回值: public void name([参数]){ //void修饰没有return返回值
… … … …
systom.out.println(…); }
public static void name(){ //静态方法可有返回值
… … … …
systom.out.println(…); }
public class Cricle {
public int r;
public float PI= 3.14f;
public void ears() {
//方法;没有返回值
float ears = PI*r*r;
System.out.println("圆的面积:"+ears);
}
public String info() {
//方法;有返回值
return "这便可算出圆的面积!";
}
}
(5)方法的重载
-
定义:在同一个类中,存在一个以上的同名方法,只要他们参数或者参数个数不同即可;
-
特点:与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别;
-
作用:方便实例化对象对方法的调用;
public class PrintStream{
public void info(int i) {
//方法重载;
System.out.println(i);
}
public void info(float f) {
System.out.println(f);
}
private void info(String s,int i) {
System.out.println(s);
System.out.println(i);
}
}
构造器
(1)定义:new对象实际上就是构造器(构造方法)
(2)作用:创建对象,给对象进行初始化赋值,方便直接调用其他属性方法;
(3)分类(依据参数):
- 无参构造器(系统默认)
eg:Person person=new Person(); new 对象实际上就是构造器(构造方法)
- 有参构造器
(4)特征
- 有与类名相同的名称
- 不声明返回值类型;
- 不被static ,final,等修饰,没有return返回值
- 每个类中至少有一个构造器;
- 默认构造器修饰符和所属修饰符一致;
- 一个类可以有多个重载构造器
- 父类构造器不可被子类继承
案例:
public class Person1 {
String name;
int age;
public Person1() {
//定义无参构造
}
public Person1(String n,int a) {
//设置有参构造
name=n;
age=a;
}
public void showInfo() {
System.out.println(name);
System.out.println(age);
}
public static void main(String[] args) {
Person1 person1= new Person1("张三",12);//显示有参构造
//new对象实际上就是构造器(构造方法)
person1.showInfo();
}
}
(5)构造器重载
作用:使得创建对象更加灵活,方便创建各种不同的对象。但参数列表不同,还提供了多个初始化new对象的模板;
public class Person1 {
String name;
int age;
public Person1() {
//构造器重载,即创建多个构造器
}
public Person1(String a) {
}
public Person1(int a) {
}
public Person1(String n,int a) {
name=n;
age=a;
}
初始化模块
(1)作用:对Java对象经行初始化
(2)程序执行顺序:成员变量默认值,代码块(静态代码块>非静态代码块),构造器代码;
public class Person {
String name;//顺序1
public Person() {
//顺序4
this.name="张三";
System.out.println("这是构造方法");
}
{
System.out.println("这是非静态代码块");//顺序3
}
static {
System.out.println("这是静态代码块");顺序2
}
}
代码块详解
(1)非静态代码块:没有static修饰的代码块
- 可以有输出语句。
- 可以对类的属性声明进行初始化操作。
- 可以调用静态和非静态的变量或方法。
- 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
- 每次创建对象的时候,都会执行一次。且先于构造器执行
(2)静态代码块:用static 修饰的代码块
- 可以有输出语句。
- 可以对类的属性声明进行初始化操作。
- 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
- 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
- 静态代码块的执行要先于非静态代码块。
- 静态代码块只执行一次
内部类
(1)定义:一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类;
(2)特点:
- 内部类名字不能和类名相同;
- 类成员可以声明为final;
- 类可以用private或protected;
- 可以声明为abstract类 ,因此可以被其它的内部类继承;
- 非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员;
lass A {
//外部类
private int s;
public class B {
//内部类
public void mb() {
//内部类方法
s = 100;
System.out.println("在内部类B中s=" + s);
}
}
public void ma() {
//外部类方法
B i = new B();
i.mb();
}
}
public class Test {
//测试类
public static void main(String args[]) {
A o = new A();
o.ma();
}
}
5、特征
封装
(1)作用:对类内部属性进行保护,只允许使用者进行访问;
(2)四种访问权限修饰符;
置于类成员定义前,用来限制对象对类成员的访问权限:
修饰符 | 类内部 | 同一个包 | 子类 | 任何地方 |
---|---|---|---|---|
private | y | |||
default() | y | y | ||
protected | y | y | y | |
public | y | y | y | y |
public权限最大在那都可被访问,default只可以被同一个包内的类进行访问;
(3)特点:通过对类属性进行private(私有的)声明,限制外部进行访问,只有public方法中的getXxx和setXxx方法得到属性和设置属性,让主方法能够访问;
//封装的类
public class Person {
private int age;//将属性(年龄)设置为private(私有的)
public int getAge() {
//取得属性
return age;
}
public void setAge(int a) {
//设置属性
this.age=a;
System.out.println(a);//返回属性值
}
}
继承
(1)定义:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。此处的多个类称为子类,单独的这个类称为父类(基类或超类)。
(2)语法:
class Subclass extends Superclass{ 类体}
(3)特性
-
提高了代码的复用性
-
让类与类之间产生了关系,提供了多态的前提;
-
子类继承了父类的属性并在基础上进行扩展,但子类不可访问父类的私有方法的成员变量和方法;
-
Java只支持单继承,不允许多继承,即一个子类只能有一个父类,一个父类可派生出多个子类;
案例:
父类:
public class Person {
private String name;
private int age;
private int sex;//1男 0女
public String getName() {
return name;
}
public void setName(String na) {
this.name=na;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age=age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
子类:
public class Student extends Person {
//进行类的继承
public void showInfo() {
System.out.println(this.getName());
System.out.println(this.getAge());
System.out.println(this.getSex());
}
主方法:
public class Text {
public static void main(String[] args) {
Student st= new Student();
st.setName("小张");
st.setAge(12);
st.setSex(1);
st.showInfo();
}
}
多态
(1)体现:方法的重载和重写
方法的重载:本类中同名方法,不同参数形式;
方法的重写:子类方法与父类方法同名时,子类对父类方法的覆盖;
public class Student extends Person {
//进行类的继承
public void setName() {
//方法的重写
System.out.println("重写父类方法setName!");
}
public void showInfo(String schoolName) {
//方法的重载
System.out.println("学校的名字:"+schoolName);
}
public void showInfo(String schoolName,int studentSum) {
//方法的重载
System.out.println("学校的名字:"+schoolName);
System.out.println("学校学生的人数"+studentSum);
}
(2)多态之向上转换和向下转换
-
向上转换:子类到父类(自动转换)
语法:父类类型 变量名1=new 子类类型
作用:只能调用父类的方法属性,不可调用子类的方法属性,当子类和父类有共同的方法名时,调用时,是子类的该方法(动态绑定);
-
向下转换:父类到子类(强制转换)
语法: 子类类型 变量名2=(子类类型) 父类类型变量名1
作用:可子类和父类的全部方法,属性;(就和子类调用一样)
public class text1 {
public static void main(String[] args) {
Animal a=new Animal();//正常实例化对象
Dog d=new Dog();//正常实例化对象
Animal dd=new Dog();//向上转换,默认转换
Dog aa=(Dog) dd;//向下转换,强制转换
aa.room="小卧室";//可调用父类,子类的方法属性
aa.showInfo();
aa.animal();
}
}
6、抽象类和接口
抽象类(abstract)
(1)定义:在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
(2)特点:
- 用abstract来修饰,不能用abstract修饰属性、私有方法、构造器、静态方法、final
- 抽象类不能被实例化;
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类;
- 抽象类中的抽象方法只是声明,不包含方法体,即不给出方法的具体功能;
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法;
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现(抽象子类外);
- 继承抽象类用extends ;
abstract class A {
//抽象类
abstract void a();//抽象方法
}
public class B extends A{
//继承抽象类
@Override
void a() {
System.out.println("重写抽象方法");
}
public static void main(String[] args) {
//测试继承类
B b=new B();//实例化对象
b.a();
new B().a();//匿名对象
}
}
接口(interface)
(1)作用:为了完成多继承;(从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现;)
(2)特点:
- 类名用interface来定义;
- 所有成员变量都默认由public static final 修饰的;
- 所有方法都默认是由 pubic abstract 修饰的;
- 接口没有构造器;
- 接口存在多层继承;
- .一个类可以实现多个接口(且要实现接口里面的抽象方法,否则被定义为抽象类),接口也可以继承其它接口(接口不能实现另一个接口);
- 继承抽象类用implements
(3)继承接口的语法:修饰符 class 类名 [extends < superclass> 继承类] [implements < interface1> [,< interface2>]继承接口 ] { 类体}
public interface Inter {
//接口
public static final int I=12;
public abstract void show();
}
public class Method implements Inter{
//继承接口
public Method(int i) {
this.i=i;
}
int i;
@Override
public void show() {
System.out.println(i*I);
}
public static void main(String[] args) {
//测试类
new Method().show();
}
}
接口和抽象类区别
(1)语法层面上的区别
- 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
- 抽象类可以有静态代码块和静态方法,而接口中不能含有静态代码块以及静态方法;
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
(2)设计层面上的区别
- 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
- 抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
模板式设计:最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;
辐射式设计:比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。就是说对于接口,如果需要添加新的方法,则所有实现这个接口的类都必须进行相应的改动。
7、对象实例化过程
(1)类对象实例化过程:
(2)子类对象实例化过程:
8、几个关键字:super,this,package,import,final,static
8.1.Super
作用:
- 用来调用父类中的属性,成员方法和构造器(语法:super.name);
- 当父类出现同名对象时,可用super来区分;
- super和this用法相似,super对父类内存空间的标识,this对本类对象引用;
实例:
//XiaoMing是Student的子类;student是Person的子类;
public class XiaoMing extends Student{
private void text() {
super.getName();//可以向上追溯到父类的父类方法和属性
super.getChool();//可以追溯使用父类的成员方法
}
}
8.2.this
(1)作用:表示当前对象,可以调用类的属性方法和构造器
(2)作用位置:在方法内需要调用的对象
注意:使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的。(实际上就是不能出现构造器自己调用自己);使用this()必须放在构造器的首行。
public Person1(String name,int a) {
this.name=name; //当前类成员变量this.name
this.age=a; //构造方法中的name
}
String name;
int age;
public void showInfo() {
System.out.println(this.name);//成员变量
System.out.println(age);
8.3. package
特点:
- 指明文件中定义的类又在的包的位置
- 包对应于文件系统的目录,package语句中,用来指明包(目录)的层次;
- 包通常用小写单词,类名首字母通常大写。
package com.hanhan.mybatis_plus;
8.4. import
(1)语法格式:import 包名[子包名]. <类名>
(2)特点:
-
若引入的包为:java.lang,则编译器默认可获取此包下的类,不需要再显示声明。
-
import语句出现在package语句之后、类定义之前
-
一个源文件中可包含多个import语句
-
可以使用import lee.* ;语句,表明导入lee包下的所有类。而lee包下sub子包内的类则不会被导入。import lee.sub.*;
-
import语句不是必需的,可坚持在类里使用其它类的全名
import com.baomidou.mybatisplus.core.metadata.IPage;
8.5. final
作用范围:
- 属性:final标记的变量为常量。名称大写,值只能赋值一次;
- 方法:final标记的方法不能被子类重写;
- 类:final标记的类不呢被继承;
修饰属性(变量):
public class Text2 {
private final static double PI=3.14;//修饰属性(变量)
public static void main(String[] args) {
int r=2;
System.out.println("圆的面积:"+(PI*r*r));
}
}
修饰方法:
public class Final {
//父类
public final void print() {
System.out.println("A");
}
}
public class Text2 extends Final{
//子类
public void print() {
//错误,final修饰方法不能被重写
System.out.println("B");
}
}
修饰类:
final class Final {
}
class B extends Final{
}//错误,不可被继承
8.6. static
(1)作用:被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问;方便在没有创建对象的情况下进行调用;
(2)作用范围:修饰属性,方法,代码块,内部类
(3)特点:
- 修饰的成员被对象所共享
- 访问权限允许时,可不创建对象,直接访问对象,直接被类调用
- 优先于对象存在
- 随着类的加载而加载
- 在static方法内部只能访问类的static属性,不能访问类的非static属性,内部不能有this;
修饰属性、方法:
public class Text1 {
public static String a="这是一个静态变量";//静态变量,作用整个类
public static void main(String[] args) {
//修饰方法
System.out.println(a);
}
}
修饰代码块:
public class Ain {
static {
//静态代码块
System.out.println("父类静态代码块");
}
}