Java 面向对象
什么是面向对象(OOP)
-
面向对象编程的本质是:以类的方式组织代码,以对象的组织(封装)数据
-
抽象
-
三大特性
- 封装
- 继承
- 多态
-
从认识论角度考虑是先有对象后有类。对象是具体的事物,类是抽象的,是对对象的抽象
-
从代码运行角度考虑是先有类后有对象。类是对象的模板
类与对象的创建
- 类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体事物
- 对象是抽象概念的具体实例
- 创建与初始化对象
- 使用new关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
构造器详解
-
构造器也称为构造方法,在进行创建对象时必须要调用构造器,特点
- 必须和类的名字相同
- 必须没有返回类型,不能写void
-
构造器作用
- 使用new关键字,本质是在调用构造器
- 构造器用来初始化值
-
构造器分类
- 默认构造
- 无参构造
- 有参构造
- 定义一个有参构造后,想使用无参构造,必须显示定义一个无参构造
- 有参构造可以有多个,实例化对象时会根据参数自动选择使用
public class Application {
public static void main(String[] arg){
// Person person = new Person();
// System.out.println(person.name);
Person person = new Person("Xiaoming");
System.out.println(person.name);
}
}
public class Person {
/*
1.默认构造器
一个类什么也不写仍然会存在一个默认构造器
会在class文件中自动生成一个无参构造器
*/
String name;
/*
2.无参构造器,用于实例初始化
初始化在new完实例后即执行
*/
// public Person(){
// this.name="Xiaoming";
// }
/*
3.使用有参构造器,必须再显示定义一个无参构造器
否则会没有无参构造
*/
public Person(){}
public Person(String name){
this.name=name;
}
}
- IDEA中可以使用alt+insert快速生成构造器
- alt+insert->constructor->选中所需的属性生成有参构造或直接选择Select None使用无参构造
小结
-
类与对象
类是一个模板,抽象,对象是一个具体的实例
-
方法
定义、调用
-
对应的引用
引用类型:除了8大基本类型外
对象是通过引用来操作的:栈->堆
-
属性:字段Field 成员变量
默认初始化:
数字:0或0.0
char:u000
boolean:false
引用:null
-
对象的创建和使用
-
类:
静态的属性 属性
动态的行为 方法
封装
-
程序设计要“高内聚,低耦合”,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:近暴露少量的方法给外部使用
-
封装(数据隐藏)禁止直接访问一个对象中数据的实际表示,通过操作接口访问
-
使用get/set访问数据,可以在get和set方法中加入属性的合法性检验代码
-
注意封装一般都是对属性封装私有,方法一般不封装
-
IDEA中可以使用alt+insert快速生成get、set函数
alt+insert->Getter and setter->选择私有属性
public class Application {
public static void main(String[] arg){
Person person = new Person();
person.setName("Xiaoming");
System.out.println(person.getName());
}
}
public class Person {
//私有属性
private String name;
//提供一些可以操作私有属性的方法 set、get方法
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
}
- 封装的意义
- 提高程序的安全性,保护数据
2. 隐藏代码实现细节
3. 统一接口
4. 系统可维护性增加
- 提高程序的安全性,保护数据
继承
-
概念
- 继承的本质是对某一批类的抽象
- extends是“扩展”的意思,子类是对父类的扩展
- Java只有单继承,没有多继承
- 继承是类与类之间的关系,除继承外,类与类之间的关系还有依赖、组合、聚合等
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)
- object类:Java中所有的类都默认直接或间接继承object类
- IDEA中使用ctrl+H可以打开类结构,查看类的继承情况
-
super与this使用
- super调用父类属性和方法,不能调用父类private属性
- this调用本类内部属性和方法
package com.yang;
public class Application {
public static void main(String[] arg){
Student student = new Student();
student.printName("application");
}
}
//Person类
public class Person {
protected String name="person";
}
//Student类
public class Student extends Person{
private String name="student";
void printName(String name){
System.out.println(name);
System.out.println(this.name);//this调用本类内部属性
System.out.println(super.name);//super调用父类
}
}
-
super调用构造器
-
在new对象时,是先调用父类的构造再调用子类构造
-
super()会调用父类的构造方法,此过程会默认执行,可以不写
-
this()会调用子类的构造方法,super()和this()都必须在子类构造方法的第一个,因此不能同时出现
-
super()默认调用的是父类的无参构造,当父类没有无参构造时就会报错
-
当父类没有无参构造时可以使用super(参数)调用父类有参构造
-
public class Application {
public static void main(String[] arg){
Student student = new Student();//在new对象时,是先调用父类的构造再调用子类构造
}
}
//父类
public class Person {
public Person() {
System.out.println("父类的无参构造");
}
}
//子类
public class Student extends Person{
public Student() {
//super();//super()会调用父类的构造方法,此过程会默认执行,可以不写
System.out.println("子类的无参构造");
}
}
-
方法的重写(属性没有重写)
- 为什么要重写
- 父类的功能,子类不一定需要或者父类的功能不一定满足子类
- 父类的静态方法和private方法都没有重写
- 重写需要有继承关系,父类重写父类方法
- 重写格式
- 子类和父类方法名相同
- 参数列表必须相同(区别重载是参数列表不同)
- 子类和父类方法体不同
- 修饰符范围可以扩大但不能缩小
- 抛出的异常范围可以被缩小,但是不能被扩大
- IDEA使用alt+insert->override可以在快速生成重写方法
- 静态方法不能重写
public class Application { public static void main(String[] arg){ //静态方法调用只和左边定义的数据类型有关 //静态方法不存在重写 B b = new B(); b.test(); A a = new B(); a.test(); } } //父类 public class A { //使用静态方法 public static void test(){ System.out.println("A->test"); } } //子类 public class B extends A{ 使用静态方法 public static void test(){ System.out.println("B->test"); } }- 非静态:重写
public class Application { public static void main(String[] arg){ B b = new B(); b.test(); A a = new B(); a.test(); } } public class A { public void test(){ System.out.println("A->test"); } } public class B extends A{ //子类重写了父类的方法 public void test(){ System.out.println("B->test"); } } - 为什么要重写
多态
- 动态编译,类型可扩展
- 同一方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多
- 多态存在的条件
- 有继承关系
- 子类重写父类的方法,不能重写的方法有static类方法、final常量、private私有
- 父类引用指向子类对象
- 多态指的都是方法的多态,属性是没有多态的
public class Application {
public static void main(String[] arg){
//多态,对象的实际类型确定,但指向的引用类型是不确定的,父类可以指向子类
//对象能调用的方法主要看对象左边的类型,与右边关系不大
//子类可以调用自己或者继承父类的方法
//父类可以指向子类,但是不能调用子类的方法
Person person = new Student();
Student student = new Student();
person.test();
student.test();
}
}
public class Person {
public void test(){
System.out.println("Person_test");
}
}
public class Student extends Person{
@Override
public void test() {
System.out.println("Student_test");
}
}
-
instanceof判断一个对象与于另一个类之间是否有关系
-
如Teacher类和Student类都继承Person类
Person person=new Student;
判断对象person和Teacher类是否有关联
-
instanceof判断过程
首先判断左边引用类型person和Teacher是否有关系,若person和Teacher无关系则编译报错
其次判断右边实例化对象类型Student和Teacher是否有关系,若有关系则返回true,无关则返回false
-
public class Application {
public static void main(String[] arg){
Person person = new Student();
System.out.println(person instanceof Object);//true
//System.out.println(person instanceof String);//编译报错
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Teacher);//false
}
}
public class Person {
}
public class Student extends Person{
}
public class Teacher extends Person{
}
-
父子类之间的类型转换
- 子类转为父类,向上转换,可直接进行
- 父类转为子类,向下转换,需要强制转换
public class Application { public static void main(String[] arg){ Student student = new Student(); Person person=student;//向上转换直接转 Student student1=(Student) person;//向下转需要强制转换 } } public class Student extends Person{ public void test(){} }
static关键字
- 使用static修饰的变量被称为类变量,方法称为类方法,使用时都是可以通过类直接调用;没有使用static修饰需要通过对象调用
- 静态代码块与匿名代码块
- 执行顺序静态代码块->匿名代码块->构造方法
- 静态代码块随类一起创建,且只执行一次
- 代码块一般用来赋初值
public class Person {
//构造函数
public Person(){
System.out.println("构造方法执行");
}
//匿名代码块
{
System.out.println("匿名代码块执行");
}
//静态代码块
static {
System.out.println("静态代码块执行");
}
public static void main(String[] args){
Person person = new Person();
System.out.println("==============");
Person person1 = new Person();//静态代码块将不再执行
}
}
-
静态导入包
import java.lang.Math; public class Application { public static void main(String[] arg){ System.out.println(Math.PI);//不使用静态导入需要使用Math.*调用方法 } } //使用static关键字静态导入包 import static java.lang.Math.PI; public class Application { public static void main(String[] arg){ System.out.println(PI);//静态导入不需要再使用Math.PI } }
抽象类(约束)
- abstract修饰符可以用来修饰方法也可以用来修饰类,抽象方法&抽象类
- 抽象类中可以没有抽象方法,但是含有抽象方法的类一定是抽象类
- 抽象类不能使用new创建对象,它是用来让子类继承的
- 抽象方法,只有方法的声明,没有实现,子类需要实现方法
- 如果子类没有实现抽象方法,那么子类也需要声明为抽象类
- 抽象类也只能单继承
public class Application {
public static void main(String[] args) {
//Action action=new Action();//抽象类不能被new
A a=new A();
a.test();
}
}
//使用abstract声明抽象类
public abstract class Action {
//使用abstract声明抽象方法
public abstract void test();
}
public class A extends Action {
//继承抽象类必须重写抽象方法
@Override
public void test() {
System.out.println("抽象类测试");
}
}
接口
-
普通类:只有具体实现
-
抽象类:既有具体实现,又有规范
-
接口:只有规范,无法自己写方法
-
接口是多继承
-
接口的关键字是interface
-
接口中定义的方法默认为public abstract,因此接口中定义方法使用
返回值类型 方法名(参数);
-
接口中一般不定义属性,如果定义属性,则均默认为常量public static final
-
接口需要重实现,实现使用关键字implements
//UserService接口定义
//接口关键字interface
public interface UserService {
//接口中定义都是抽象的public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
//TimeService接口定义
public interface TimeService {
void timer();
}
//多继承同时实现UserService和TimeService
//接口实现关键字implements
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
内部类
-
内部类就是在一个类内部再定义一个类
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
本文来自博客园,作者:{Ray963},转载请注明原文链接:{https://www.cnblogs.com/ray93/}

浙公网安备 33010602011771号