JAVA基础之面向对象
文章目录
JAVA是一门面向对象的编程语言,那么什么是面向对象呢?首先,我们来了解一下编程的两种思想方式
面向过程
什么是面向过程:
面向过程POP
(Procedure Oriented Programming),是一种基本的编程思想,在面对一个需要解决的问题时,将问题按流程逐步实现,注重执行的细节。
面向对象
面向对象OOP
(Object Oriented Programming),所有事情在需要时让各个对象执行,注重创建解决问题的对象。在面向对象中,给对象设计的方法,其实就是面向过程的。
这种思想致力于将计算机中的世界,描述的和现实中一致。
两种思想处理同一种问题
如做饭。
如果用POP:得到大米、得到锅、得到水、煮饭。。。
如果用OOP:创建一个能做饭的工具:电饭煲,让电饭煲拥有做饭的行为,调用该行为即可。
如组装电脑。
POP:列举所有配件,自己去商场购买,自己带回家,自己组装。
OOP:让伯伯推荐配件,让弟弟去商场购买,让快递送回家,让邻居组装。
理解
-
面向过程:亲力亲为,侧重于分析过程。
-
面向对象:所有事情交给相应的对象完成,侧重于如何创建对象。
对象和类
对象Object
某个类的具体实例,用于执行其类中的方法。
创建对象
类名 对象名 = new 构造方法(参数);
类Class
是一系列拥有相同属性和行为的对象的集合。是对象的模板。
定义类
[修饰符] class 类{
//属性,定义变量
//行为,定义方法
}
类和对象的关系
-
对象是类的具体表现,类是对象的合集(模板)。
-
如包饺子时的模具就是一个类,每次用模具包出来的饺子都是一个个对象。
-
先定义模板类,才能通过类创建出对象。
成员变量、局部变量、静态常量
-
成员变量:定义在类中的变量,使用范围在该类中,也称为这个类的属性,它有默认值,在对象创 建时创建,通过对象访问。
-
静态常量:特殊的成员变量,使用范围在该类中,用static和final修饰,它通常需要在定义时赋值,在类加载时就创建,通过类名方法。
-
局部变量:定义在方法中的变量,使用范围在该方法中,它没有默认值,在赋值后才能使用,在方 法调用时创建。
class Person{
//成员变量
String name;//默认null
//静态常量
final static String country="中国";
//定义方法
void info(){
//局部变量,需要赋值才能使用
int age=20;
System.out.println("我是"+country+"人,名叫"+name+",今年"+age+"岁");
}
}
构造方法
[访问修饰符] 类名(){
}
-
没有返回值部分,方法名必须和类名一致
-
在使用new关键字创建对象时自动调用对应的构造方法
-
每个类在定义后,隐藏有一个默认的无参数的构造方法
-
如果自己写了一个构造方法后,默认隐藏的无参数的构造方法就会失效
-
构造方法通常用于初始化成员变量
-
构造方法之间都是重载关系,构造方法不能重写
-
构造方法执行时,不一定会创建对象。如抽象类中有构造方法,但该构造方法只在创建其子类对象 时自动调用。
面向对象的三大特性
封装
使用private关键字对属性进行修饰,可以防止除自身类之外的地方对该属性进行访问。
这样可以保护关键属性,隐藏类内部的实现细节,再对外提供一组公开的get/set方法用于对该属性的赋值和读取。
步骤
-
创建类,编写成员变量(属性),给成员变量添加private修饰符
-
给成员变量写一个公开的setXXX方法
-
给成员变量写一个公开的getXXX方法
-
访问时不能通过.访问,只能通过setXXX和getXXX访问
public class Person{
private String name;
private int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public class Main(){
public static void main(String[] args){
Person p = new Person();
//p.name="xxx";//无法直接通过.访问name属性
p.setName("小明");//通过间接的方式赋值
System.out.println(p.getName());//通过间接的方式读取
}
}
}
使用IDEA自动生成getter/setter方法
在类中,右键generator或快捷键alt+insert,选择getter and setter,选择要封装的属性。
继承
类A可以通过extends关键字继承类B。
语法:class 类A extends 类B
- 类A称为子类、派生类、衍生类、subClass
- 类B称为父类、基类、超类、superClass
- 继承后,子类可以访问父类中非私有的属性和方法。
- 不同的子类中相同的代码,都可以定义在父类中,减少子类中的代码冗余。
如小孩类和老人类都有姓名、年龄等属性,都有吃、睡等方法,那么就可以定义一个人类,将这些属性和方法写在里面,让小孩类和老人类继承人类。
特点
- 如果多个类之中有相同或类似的代码,可以将这些代码提出来定义在一个公共的类中,这个类就是父类。再让那些类去继承这个父类,这样就能减少子类的重复代码
- 子类对象可以直接访问父类中非私有的属性和方法
- 子类可以对父类中的方法进行拓展或覆盖,这称为方法重写,重写后,子类对象再调用该方法时,执行的是重写后的内容。
- java中是单继承,一个子类只能有一个父类,一个父类可以有多个子类。
- java中可以多重继承,类A可以继承类B,类B也可以继承类C,这时类A可以访问类B和类C中非私有的成员。
- 任何类都是Object类的子类。
- 在创建子类对象时,先执行父类中相应的构造方法。
多态
多态是面向对象语言的一种特性,通常在代码中用于:需要使用一个父类对象时,实际传递的是一个子类对象,这时可以将子类对象当做父类对象使用。这种特性称为多态。
如果使用多态,就可以不用重载那些方法,只需要定义一个参数为所有图形的父类,调用该父类对象的计算方法。具体计算方法交给子类重写。这样就免去了重载的过程,只定义一个参数为父类对象的方法,实际传递子类对象,调用方法时执行的是子类重写后的内容。
父类 对象 = new 子类();
interface USB{
void start();
}
class Mouse implements USB{
void start(){
//重写方法
}
}
class Computer{
void powerOn(USB usb){
usb.start();
}
}
class Main{
public static void main(String[] args){
//接口不能创建对象
//new USB();
//创建子类对象,保存到父类/父接口的变量中
USB usb=new Mouse();
//在需要使用父类/父接口对象时,实际传递子类对象
new Coumpter().powerOn(usb);
}
}
特殊的方法
重写override
子类继承父类后,对父类中的某个非私有方法进行重写,达到拓展或重做的目的。
- 重写必须要求方法名、方法返回值、方法参数列表必须相同
- 访问权限不能比父类更严格
- 不能抛出比父类更大的异常
重载overload
在一个类中,某个方法在不同的参数下,表现不同的效果。同名不同参。
- 方法名必须相同
- 方法参数列表必须不同(类型和数量)
- 与返回值无关
this和super
-
都可以当做对象或构造方法使用。
-
当做对象:this表示当前类的对象,super表示当前类的父类对象
-
this或super当对象时,只能用在非静态方法中。
-
当做构造方法:this()表示当前类的无参构造方法,super()表示当前类的父类的无参构造方法
-
this或super当构造方法时,只能放在另一个构造方法的第一行。
-
每个继承关系中,如果父类和子类都没有重载构造方法时,子类里都有一个默认无参的构造方法,其中 在调用父类的无参的构造方法
class Father{ } class Son extends Fahter{ //这段代码是隐藏的 Son(){ super(); } }
-
如果重载了父类的构造方法,在子类的构造方法中,一定要调用父类的某个重载的构造方法
class Father{ Father(String str){} } //继承时就会报错 class Son extends Fahter{ //子类的构造方法中,一定要调用父类的某个构造方法 Son(){ super("xxx"); } }
Object类
是所有类的根类。任何类都直接或间接的继承了该类,但没有显式地写出来。所有类都可以调用或重写Object类中的方法。
toString()
在输出某个对象时自动调用的方法,默认Object中输出的是"对象所在类的全限定名@十六进制 哈希码"。
通常自己定义的类需要重写该方法,用于输出该对象中的属性。
equals()是比较两个对象是否相同的方法,默认Object中使用==比较,所以自定义类后,如果要比较该 类的对象,一定要重写equals方法和hashcode方法,根据指定参数比较两个对象是否相同。
向上转型
子类对象保存到父类的变量中。
Person p =new Person();
Object obj=p;
向下转型
父类对象强行保存到子类的变量中。
Object obj=new Object();
Person p=(Person)obj;
final
用于修饰属性、方法和类
修饰属性:变量变为常量,不能改变其值。修饰方法:方法不能被重写。
修饰类:类不能被继承。
abstract
用于修饰类和方法,表示抽象的。
修饰方法,该方法称为抽象方法,没有方法体,同时该方法所在类一定也要使用abstract修饰成为抽象类。
- 抽象方法只能出现在抽象类中,不能出现在普通类中。
- 抽象类中可以没有抽象方法
- 抽象类中有构造方法,但该构造方法不能使用new调用,所以抽象类不能创建对象
- 抽象类中的构造方法,在创建其子类对象时自动调用
- 抽象类通常需要被继承,继承后子类一定要重写抽象类中的所有抽象方
interface
用于定义接口的关键字。代替原本的class
如果某个抽象类中,全是抽象方法时,可以将该抽象类定义为一个接口。
接口是一个完全抽象类。其中的方法都是公共的public抽象abstract方法,其中的属性都是公共的public 静态static常量final。在jdk1.8后,接口中可以定义默认default方法和静态static方法。
-
接口中的方法都是被public abastract修饰,可以不用写出来
-
接口中的属性都是被public static final修饰,可以不用写出来
- jdk1.8后,可以在接口中定义default方法和static方法
-
接口通常需要一个类去实现,该类使用implements关键字实现接口。
-
实现了接口的实现类,要重写其中所有抽象方法
-
接口没有构造方法,不能实例化对象
static
可以修饰方法和属性,表示该方法或属性是静态的,在类加载时保存到内存中,无需对象参数,直接通 过类名就能访问。
如果某个属性或方法被高度重用时,可以将其定义为静态的,之后直接通过类名调用。
还可以在类中定义静态代码块static{}。在类加载时自动执行的代码块。
感悟
Java属于面向对象编程,面向对象的思想是java的核心思想。学习java领悟了面向对象思想,并运用到实际的编程中去,才真正算是一名合格的java工程师。