面向对象概述
面向对象是一种编程思想,不再是像面向过程那样一步一步地去实现操作,而是把这些操作交给对象来处理
类与对象
概述
众多实物具有的共同特征提取出来的集合,封装成一个类.
类的定义:
修饰符 类名{
成员属性;
构造器;
成员方法;
}
类的成员
成员变量
成员变量,也叫属性。
与局部变量的区别:
- 定义的位置
- 成员变量定义在类中、方法外
- 局部变量定义在方法上或者方法内
- 初始化值
- 成员变量有初始化值【默认值】
- 局部变量没有初始化值,必须显式赋值
- 在内存中的位置
- 成员变量在堆内存中
- 局部变量在栈内存中
- 生命周期
- 成员变量随着对象的加载而加载,随着对象的结束而结束
- 局部变量随着方法的加载而加载,随着方法的结束而结束
修饰符:public、protected、缺省、private、final、static
可以被以上修饰符所修饰
构造器
也叫构造方法,与类名相同,可以发生重载,用于创建对象的时候对属性进行赋值
在Java中,如果我们没有定义构造器,那么JVM会自动给我们创造一个无参的构造器,如果我们自己定义了一个构造器,那么就不会再给我们提供
创建对象:类名 变量值 = new 构造器
# 下面是一个Book类的两个构造器:
public Book() {
}
public Book(String name, double price) {
this.name = name;
this.price = price;
}
# 创建对象示例:
Book book1 = new Book();
Book book2 = new Book("java",50.0);
成员方法
对象共有的行为,用来实现某一操作,这里是面向过程的思想,和前面的方法定义一样,成员方法一般用来获取属性值。
代码块
分类:
- 构造代码块:类内方法外,随着创建对象而运行,但是优先于构造器运行
- 局部代码块:写在方法的内部,主要作用就是划分变量的作用域
- 静态代码块:被static修饰,只运行一次,在所有代码之前。
- 同步代码块:用来同步共享数据
对象
对象就是类的实体,具有类里面定义的属性与方法,通过对象名.属性|方法 进行时使用
三大特性
封装性
概述:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
关键字:private
private:私有的,可以修饰成员变量、方法、构造器。
特点:被private修饰的内容,外界无法直接获取,这一关键字就体现出了Java的封装性
关键字:this
this:表示调用方法或者属性的对象
访问内容:成员变量、成员方法、构造器
# 示例:将形参name与price赋值给属性name与price
public Book(String name, double price) {
this.name = name;
this.price = price;
}
# 访问方法:this.方法()
# 访问构造器:this()或者this(参数)
关键字:static
static的几个特点:
- 共享功能:如果一个类里面定义了一个静态属性,那么通这个类创建的对象共享这一个是属性。如果有一个对昂修改了这个值,那么 其他对象的这个属性值会随之修饰
- 加载时机:随着类的加载而加载,因为类只加载一次,因此静态属性或者方法也只加载一次,也是static具有共享功能的原因
- 调用方式:可以通过类名或者对象名去调用
- 静态的位置:1.6的时候在方法区,从1.7开始在堆内存中
注意事项:在一个静态方法中,static和this|super不可共存,因为后者都是返回调用对象,因为static的加载优先于对象
继承性
概述
将多个类中相同的部分提取到单独一个类中,其他类与这个类产生继承关系。
作用
其他类可以通过继承自这个类,此时这个类就是父类,子类中就会有从父类继承而来的方法,可以供自己调用
方法重写
如果继承而来的父类方法满足不了我们的需求,那么我们可以对其更改,以此实现对方法的重写或者覆盖
方法重写的几个注意事项
-
子类重写的方法
必须
和父类被重写的方法具有相同的方法名称
、参数列表
-
子类重写的方法的返回值类型
不能大于
父类被重写的方法的返回值类型。【例如:Student < Person】注意:如果返回值类型是基本类型或者void,那么重写后必须也要保证相同
-
子类重写的方法使用的访问权限
不能小于
父类被重写的方法的访问权限。(public > protected > 缺省 > private)跨包的父类缺省的方法不能重写
关键字:final
final,最终的,被它修饰的一切都不可以改变
比如final int i= 7;后续不可以出现i= 5;不可以改变指的是这样赋值改变,但是可以final int i = 5;直接从定义的根源上进行改变
可以修饰的内容:
- 方法:表示该方法不可以被重写
- 类:表示该类不可以继承
- 变量:变量被final修饰后会变成常量,常量名建议大写
关键字:extends与super
extends:
- 表示继承,class A extends B
- 对于类而言,不可以同时继承多个类,但是可以多重继承【子类继承父类 ,父类再继承它的父类……】
super:
- 表示当前类的直接父类,可以调用成员变量、方法、构造器等,与this的使用一样
- 不可以调用私有成员
注意:如果super调用父类的方法,那么只是把代码的逻辑拿到子类里执行,并非是在父类里面执行,将来如果涉及到就近原则要注意这一点
继承的注意事项
-
继承之一调用
- 子类的构造器的第一行默认super(),调用的父类的无参构造器,
- 子类构造器的第一行必须是父类的构造器,否则无法完成子类对象的实例化
-
继承之两不改
-
被static修饰的方法不可以更改【或者说是不可以重写】
-
被final修饰的成员不可以更改
-
-
继承之三不可
- 被final修饰的类不可以继承
- 私有化成员不可以继承
- 不可以继承构造器
多态性
概述
同一个事物再不同时刻下的不同状态
实现多态的条件
- 要有继承关系
- 要有方法的重写【可以不重写,但是这样的话,实现多态的意义不大】
- 父类的引用指向子类的对象:父类 变量名 = new 子类();
向上转型与向下转型
向上转型
- 格式:父类 变量名 = new 子类();
- 只能调用父类的属性
- 可以调用子类父类都有的方法,但是最终实现是子类的方法实现
向下转型
- 格式:父类 父类的变量名 = new 子类(); 子类 子类的变量名 = (子类)父类的变量名;
- 作用:可以调用子类的属性和特有的方法
向上转型执行成员的特点
- 成员变量:编译看左,运行看左
- 成员方法:编译看作,运行看右
- 静态方法:编译看左,运行看左
抽象类
概述
被abstract修饰的类就是抽象类,没有具体的实现,只是概念性的东西
抽象类的成员
- 属性:可以是变量,也可以是常量
- 方法:可抽象,可具体
- 构造器:抽象类的构造器一定是私有化的,不可以实例化,但是可以帮助子类进行实例化
抽象类的特点
- 有抽象方法的类一定是抽象类
- 抽象类里可以有抽象方法,也可以有具体方法
- 抽象类不可以实例化,只能通过子类去创建对象
- 抽象类的子类可以是抽象类,也可以是具体的子类
- 如果具体的子类继承了抽象类,那么必须要重写抽象类的所有抽象方法
- 如果抽象类继承了抽象类,可以选择性地重写抽象类的抽象方法
接口
概述
主要是为了提供一个类的扩展功能,可以被看成一个特殊的类
关键字 implements:用来实现接口的功能
接口的成员
- 抽象方法:接口的方法只能是抽象方法
- 常量:接口里只能有常量,不可以有变量
特点
- 一个类可以实现多个接口,接口之间用逗号隔开
- 具体的类实现接口时,必须要重写里面的所有的抽象方法
- 接口没有构造器,不可以实例化,自己写的也不行】
- 接口可以多重继承
注意:接口是特殊的类【因为底层编译时,接口也会被编译成.class文件】,因此类也可以多重继承,但仅限于接口这种特殊的类
引用类型传参【类】
接收参数:
- 如果接收的类型是一个普通的类,可以传入本类或者该类的子类对象
- 如果接收的类型是一个抽象类,必须传入一个该类的具体子类对象
- 如果接收的类型是一个接口,必须传入一个实现了该接口的具体子类对象
返回参数:
- 如果返回值的类型是一个普通的类,可以返回本类或者该类的子类的对象
- 如果返回值的类型是一个抽象类,必须返回一个该类的具体子类对象
- 如果返回值的类型是一个接口,必须传入一个实现了该接口的具体子类对象
内部类
分类:参考变量的角度进行分析
- 局部内部类:声明在方法内、构造器内、代码块内等
- 匿名的局部内部类
- 有名的局部内部类
- 成员内部类:直接声明在外部类的里面方法等结构的外面
- 非静态的成员内部类
- 静态的成员内部类
成员内部类的理解:
- 可以被四种权限修饰符修饰
- 可以被static修饰
- 可以调用外部类的其他结构(属性、方法等)【包括私有的成员】
内部类的基本使用
# ①:创建静态内部类的对象
Outer.Inner inner = new Outer.Inner();
# ②:创建非静态内部类的对象
Outer.Inner inner = new Outer().new Inner();
或
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
# ③:调用外部类的属性或者方法
Outer.this.属性|方法
# ④:调用自身的属性或者方法
this.属性|方法
成员内部类示例:
public class Outer {
private int i;
public Outer(){
}
class Inner{
private int i;
public void fun(){
System.out.println(i);
System.out.println(Outer.this.i);
Outer.this.i = 7;
System.out.println(Outer.this.i);
}
}
public void fun() {
i = 10;
}
public static void main(String[] args) {
// Outer outer = new Outer();
// outer.fun();
// Outer.Inner inner = new Outer().new Inner();
// inner.fun(); // 0 0 7
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
outer.fun();
inner.fun(); // 0 10 7
}
}
匿名内部类示例:
public interface Sing {
void sing();
}
public class Bird implements Sing{
@Override
public void sing() {
System.out.println("鸟会唱歌");
}
}
# 上面是一个经典写法,写一个类实现接口,然后创建对象调用,如果我们只是需要实现接口的效果,并不需要中间的类,就会造成大量的代码冗余
public class SingTest {
public static void main(String[] args) {
new Sing(){
@Override
public void sing() {
System.out.println("鸟会大声唱歌");
}
}.sing();
}
}
# 这是匿名内部类的写法,直接new Sing(){……}.sing();底层会帮我们自动创建一个类,然后完成调用方法
权限修饰符
修饰符 | 本类 | 本包 | 其他包子类 | 其他包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
缺省 | √ | √【本包子类与非子类都可见】 | × | × |
protected | √ | √【本包子类与非子类都可见】 | √【其他包中仅限于子类可见】 | × |
public | √ | √ | √ | √ |
其中只有:public 、缺省 可以修饰外部类
标签:Outer,子类,面向对象,new,父类,方法,public From: https://www.cnblogs.com/ajnq-fz/p/18679924