面向对象与面向过程的差异
面向过程
线性思维,考虑步骤,循序渐进,第一步应该如何,第二步......适合处理简单的问题
面向对象
将对象问题进行抽象分类,对各个类进行单独思考,但是操作仍是面向过程的思维,适合处理复杂的问题
什么是面向对象
抽象
本质
以类的方式组织代码,以对象组织(封装)数据
三大特性
封装
继承
多态
类与对象的创建
对象的创建
类名<空格>对象名 = new.类名();
new.类名()会返回一个自己的对象,此过程也称为类的实例化,此外还会分配内存空间,对对象的默认初始化,以及对类构造器的调用
类的部分知识
类中只有属性与方法,属性没有初始值,可以通过构造器来赋初值
在类中this指向该类,可以是属性也可以是方法,如:this.name指向类的属性name
构造器
类构造器本身是一个方法,具有以下特点
1.方法名必须和类名一致
2.没有返回值,也不能写void
一个类即使声明也不写也会存在一个方法(构造方法,在class文件中可见) 有参构造:一旦定义了有参构造,无参就必须显示定义(构造器的重载) 两个构造器都存在时,根据有无参数判断调用哪个构造器
快捷键:Alt + insert 快捷生成构造器
构造器的作用
1.给类属性赋初值
2.使用New关键字本质就是在调用构造器
创建对象内存分析
方法区属于栈区
静态方法区和类一起加载(最开始就会加载),并且所有人都可以调用 Application与Pet都是类,里面包含了常量池(字符串常量,字符常量等),以及一些非静态方法都会加载 在New一个新的对象后,并使用一个变量接收返回的对象以后,栈区会出现一个引用变量名,该变量名保存一个指向堆区某个对象的地址
封装
封装的关键:属性私有
public(公共)所有人都可以访问
private(私有)不可直接访问
访问主要使用get/set进行
set用于改变属性值
get用于获取属性值
一般在类中对于一个私有属性会设置两个方法,例如属性名name,则有两个方法getName,setName
public class Person {
private String name;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
在创建一个新对象后就可以使用两个方法对私有属性进行访问
继承(extends)
继承的本质是对于类的抽象
子类会继承父类的所有方法与属性(包括私有属性),在java中所有类默认继承object类
注意:只有单继承(只有一个父类,父类可以有很多子类)
快捷键:control + H 显示继承树
继承的使用
在子类名后加上extends 父类名
父子类重名情况
如果父类属性与子类属性出行重名情况,在创建一个子类新对象时
直接访问属性访问的是子类的属性(子类名.属性 this.name)
使用super.name才是访问父类的name属性
方法同理
Super详解
构造器的调用:this()子类构造器调用,super()父类构造器的调用
创建子类对象时调用构造器时会先调用父类构造器,Super()只能位于子构造器的第一行,super()一般被隐藏在子类构造器第一行
Super注意点:
1.super只能出现在子类方法或子类构造方法中
2.this和super不能同时出现在构造方法
3.super()只能在第一行
4.super只能在继承的情况下使用
注意:如果父类只有参构造器,子类就不能出现无参构造器,且构造器中必须写出super(形参)在第一行(父有子有,父无子无)
方法的重写
public class demo {
public static void main(String[] args) {
A a = new A();
a.test();
B b = new A();
b.test();
}
}
A为子类,B为父类
当方法为静态时,b调用的是B类的方法,所以使用的是B类中的test
当方法为动态时,b调用的是对象的方法,而b是用A类创建的,所以使用的是A类中的test
(静看左,动看右 子类不能重写静态方法)
注意:
1.子类与父类中重写的目标方法方法名必须相同
2.参数列表必须相同
3.修饰符范围可以扩大不能缩小
private>Protected>Default>public
4.抛出异常(范围可以缩小,不能扩大)
ClassNotFoundException --> Exception(大)
5.必须要有继承关系
方法体可以不同,其它可以相同
为何需要重写?
父类的功能子类不一定需要,或子类不一定满足
快捷键:Alt + insert
多态
基于继承
父类的引用类型指向一个子类对象
注意:多态是指方法的多态,不是属性的多态
在调用方法时,如果父子同时拥有相同的方法(方法的重写),则执行子类的方法,若子无则执行父类的方法,但是不可调用子类独有的方法,但是可以强制转换类型为子类,即可调用
当方法被 static final private修饰时,不能对方法重写,也就没有该方法的多态
((子类名)对象名).方法名
Instanceof和类型转换
instanceof
语法:引用变量 instanceof 类名
功能:判断前面的引用变量是否属于后面的类,或者属于其子类,所以不看引用类型而要看使用哪个类创建了该对象
注意:instanceof前面的引用变量编译时的类型要么和后面的类型相同,要么与后面的类型具有父子继承的关系
类型转换
转换方法:((类名)引用变量)
向上转型自动转换
向下转型需要强制转换
子类转换为父类可能会丢失一些方法
Static部分知识
用类名不能访问非static类型的属性
实例化后可以访问
代码块
非静态代码块,在构造器之前创建,静态代码块和类一起加载,且静态代码块只执行一次
public class demo {
{
//匿名代码块
System.out.println("匿名代码块");
}
static {
//静态代码块
System.out.println("静态代码块");
}
public demo(){
System.out.println("构造器");
}
public static void main(String[] args) {
demo demo = new demo();
System.out.println("=========");
demo demo1 = new demo();
}
}
静态导入包
静态导入包中的方法可以直接调用
抽象类
修饰类sbstract
抽象方法只能存在于抽象类中,只有方法名字,没有方法的实现,具有约束性
普通方法也可以存在于抽象类中
抽象类不可以被New
抽象方法可以被子类继承,但是子类必须实现该方法,否则子类也无法被new,同理子类也是抽象类,则需要子子类实现抽象方法才能被New
接口的定义与实现
只有规范(抽象方法):约束与实现分离
面向接口编程
接口的定义:
public interface(接口) 类名(){}
实现接口的命名规范:接口名+Impl
实现接口的类必须重写全部接口中的方法
在接口中定义的常量会有默认修饰(public,static,final)
接口中的方法默认修饰(public abstract)
实现接口类的定义: 类名+implements(实现)+接口名...{}
作用
1.约束
2.定义一些方法,让不同的人实现
3.接口不能被实例化,接口中没有构造方法
4.implement可以实现多个接口
5.必须重写接口中的方法