面向对象思想:
不同对象之间相互访问--》 new 对象().方法
思想就是懒人思想,找人帮忙做
面向对象三大特征:封装、继承、多态
1.继承
继承(Inheritance)是面向对象编程中的一种重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。继承有助于实现代码重用和扩展,建立类之间的层次关系。在Java中,继承是通过使用`extends`关键字实现的。
public class 子类名 extends 父类名{
}
1.1继承特点
1. 子类可以继承父类的非私有成员(成员变量、成员方法)。这意味着子类可以拥有父类的方法和变量,并且可以在子类中直接使用它们,有助于实现代码重用,从而避免在各个子类中重复编写相同的代码。
2. 继承支持多层继承。在Java中,类是单继承的,即一个类只能有一个父类。但是,它支持多层继承,也就是说,一个类可以继承另一个类的子类,就形成儿子继承父亲,父亲继承爷爷的家谱。
3. 子类可以覆盖(Override)父类的方法。覆盖是指子类重新定义父类的方法,以实现不同的功能。这使得子类可以根据需求对父类的方法进行修改或扩展。
4. 继承有助于实现封装。通过继承,子类可以隐藏其内部实现,而只暴露公共接口给外部使用。这样可以提高代码的封装性和可维护性。
public class Father {
private String name;
private int age;
int fu=100;
int num=222;
public Father() {
System.out.println("我是父类的空参构造");
}
public Father(String name, int age) {
this.name = name;
this.age = age;
System.out.println("我是父类的全参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println("人要吃饭");
}
protected void makeMoney(){
System.out.println("我要挣钱");
}
}
public class Son extends Person {
int num=111;
int zi=50;
public Son() {
System.out.println("我是子类的空参构造");
}
public Son(String name, int age) {
super(name, age);
System.out.println("我是子类继承父类的全参构造");
}
public void a(int num){
System.out.println(num);
}
public void b(int num){
System.out.println(this.num);
}
public void c(int num){
System.out.println(super.num);
}
@Override
public void makeMoney(){
System.out.println("能挣钱");
System.out.println("赚了多少钱");
}
}
1.2匿名对象(了解)
创建对象时不给名字 new 类名();
使用:new 类名().方法名
使用场景:如果只是简单调用一些方法可以用,如果是给对象属性赋值就不可以
//匿名Father类
new Father().eat();
new Father().setAge(16);//与后面的Father类对象无关,是重新new的
System.out.println(new Father().getAge());
1.3继承中成员变量的访问特点
1.变量不重名:
如果new的是父类对象,只能调用父类的
如果new的是子类对象,既能掉子类自己的,也能掉从父类继承的(非私有)
2.变量重名:
看等号左边是谁,先调用谁的成员,子类如果没有,找父类
3.当子类中成员变量和局部变量跟父类中的成员变量重名
this.成员变量:代表的是自己的成员变量
super.成员变量:代表的是父类的成员变量
1.4继承中成员方法的访问特点
1.不重名:
如果new的是父类对象,只能调用父类的
如果new的是子类对象,既能调子类自己的,也能调用父类继承的(非私有)
2.重名:
看new的是谁就先调用谁的方法,子类没有就找父类
Son son1=new Son();
System.out.println(son1.num);
Father fa = new Father();
int i = fa.fu;//父类对象调父类变量
System.out.println(i);
int ii = son1.zi;//子类对象调子类变量
System.out.println(ii);
int iii = son1.fu;//子类对象调父类变量
System.out.println(iii);
fa.eat();//父类对象调父类方法
son1.eat();//子类对象调父类变量
fa.makeMoney();//父类对象调父类变量
son1.makeMoney();//子类对象调子类变量
//fa.a();//父类不能调用子类方法
son1.a(999);//子类对象调子类变量
son1.b(999);
son1.c(999);
1.5方法的重写
1.方法的重载 (overload)方法名相同,参数列表不同
2.方法的重写 (override)子类和父类有一样的方法。注解: @override --》 检测该方法是不是重写的方法前提:必须有子父类继承关系
3.注意事项
a.子类方法覆盖父类方法,必须保证权限大于等于父类权限。
public->protected->默认的->private)
b.子类方法覆盖父类方法,返回值类型、函数名和参数列表必须一模一样
c.私有方法不能被重写(父类私有方法是不能被子类继承)
4.重写场景
子类想要对父类中的方法的功能进行增强
注意:构造方法能重写吗?
构造方法方法名等于类名
父类名不能等于子类名字
所以不能重写
1.6 super和this
super:代表的是父类对象
1.每一个构造方法中,第一行默认有一个super () --》代表的是父类的构造方法创建子类对象之前会创建父类对象。
2.
调用父类的成员变量-->在子类中super.成员变量名
调用父类的成员方法-->在子类中super.方法名 (参数)
调用父类的构造方法-->在子类构造方法中 super() 或者super(参数)
this:
a.this调用本类构造方法的时候 需要写在构造方法的第一行
b.在构造方法中,this和super不能同时存在
c.不要用this在有参和空参之间来回调用 (死循环)
2.抽象
1.抽象:说不明道不明
2.注意事项:
A。将所有公共的方法抽取出来,每个类实现方式不同,所有抽出来的方法并不能确定功能。这个方法就是抽象方法。
B. 抽象方法所在的类 必须是抽象类。
C. 抽象类中不一定非得有抽象方法,构造方法,普通方法,静态方法
D.抽象方法中不能new对象。需要通过子类去实现抽象方法。
3. 使用:
a.定义抽象类:
修饰符 abstract class 类名{
}
b.定义抽象方法:
修饰符 abstract 返回值类型 方法名(参数);
c.创建子类对象 继承父类,重写抽象方法。
d.创建子类对象 调用子类重写方法。
public abstract class Animal {
//定义一个抽象方法
public abstract void eat();
}
public class Dog extends Animal {
//重写eat方法
public void eat(){
System.out.println("狗吃肉");
}
}
public class Test {
public static void main(String[] args) {
Dog dog =new Dog();
dog.eat();
}
}
3.接口
1.概念:就是一种标准,规范。
2.接口的定义格式;
interface 接口名{}
public interface USB {
}
3.1接口中的抽象方法
1.定义格式;
即时不写 abstract 默认也有
public abstract 返回值类型 方法名(参数);
2.使用:
a.定义一个实现类 , 实现接口---> 类名 implements 接口名
b.必须实现所有抽象方法
c.创建实现类对象(接口不能直接new对象),调用重写的方法。
//USB接口
public interface USB {
public abstract void open();
public void close();
void method();
}
//实现类1
public class Mouse implements USB{
@Override
public void open() {
System.out.println("我打开了");
}
@Override
public void close() {
System.out.println("我关闭了");
}
@Override
public void method() {
System.out.println("w shi ge fangfa");
}
}
//实现类2
public class Pc implements USB{
@Override
public void open() {
}
@Override
public void close() {
}
@Override
public void method() {
}
}
3.2抽象类和接口的区别
1. 定义:抽象类:一般作为父类来使用,可以包含 构造方法 , 成员变量, 普通方法,静态方法,抽象方法,它用于作为其他类的基类。接口是一个纯粹的规范,功能的合集,它只包含抽象方法和常量的定义,用于描述类应该具有的行为。
2. 实现方式:一个类只能继承一个抽象类,但可以实现多个接口。这意味着一个类可以通过继承抽象类来获得一些共享的实现代码,同时通过实现接口来满足多个规范。
3. 构造函数:抽象类可以有构造函数,而接口不能有构造函数。因为接口只是一种规范,不涉及对象的实例化。
4. 默认实现:抽象类可以包含具体的方法实现,子类可以直接继承这些实现。接口只能定义抽象方法,不包含具体的实现,子类必须实现接口中定义的所有方法。
5. 使用情况:抽象类适用于具有共享代码和行为的类层次结构,它可以提供一些通用的实现。接口适用于描述类应该具有的行为,提供一种规范,使得不同的类可以实现相同的接口,从而实现多态性。
总的来说,抽象类更适合于类层次结构的设计,而接口更适合于定义类的行为规范。在实际应用中,需要根据具体的需求和设计目标来选择使用抽象类还是接口。
3.3接口特点(了解中的了解)
1.接口可以多实现。(一个类可以同时实现多个接口)-->必须要重写所有接口中的所有抽象方法。
类 implements 接口1,接口2
2.接口可以多继承 (一个接口可以同时继承一个或者多个接口)
接口 extends 接口1,接口2.
3.一个类可以继承一个父类的同时实现一个或多个接口 (类 dxtends 父类 implements 接口1,接口2)
4.多态
1.概述:一个事物的不同形态:
cut 这个单词 理发店是剪头发 但是拍电影就是停止。
2.条件:
a.子父类继承关系(接口,实现关系)
b.必须有方法的重写
c.父类引用指向子类---> 父类 对象名= new 子类();
接口名 接口 =new 实现类();
只能调用重写方法,不能调用子类特有方法
public class Test2 {
public static void main(String[] args) {
//多态写法
USB usb =new Mouse();
usb.open();
usb=new Pc();
//正常写法
Mouse mouse =new Mouse();
mouse.open();
Pc pc =new Pc();
}
}
4.1多态中成员变量和成员方法的访问特点(重点)
* 多态调用成员变量 看等号左边是谁就调用谁的
* 多态调用成员方法 , 看new的是谁就调用谁。如果子类没有去父类找
Animal animal=new Dog();
System.out.println(animal.a);
animal.eat();//new的是Dog,所以调用Dog的eat方法,如果Dog中没有该方法才调用父类的
//如果animal.成员变量则是Animal类中的成员变量
4.2多态的转型(重点)
1.向上转型 eg:父类 对象名 =new 子类();
父类引用指向子类对象
弊端:不能直接调用子类的特有方法。
2.向下转型 eg:子类 对象名= (子类)父类对象名--》
向下转型-》 可以调用子类特有方法。
就像 double b =10;
int i =b ;--- 报错,强转 --》 int i =(int)b;
3.问题:
不存在关系的两个转换会报错。
Animal animal =new Dog();
//animal.eat();
//animal.lookDoor(); 不能调用特有方法;
Cat cat =(Cat)animal;//此时该animal是Dog类对象
cat.catchMouse();
会报错ClassCastException: Dog cannot be cast to Cat
类型转换异常 猫不能转成狗。
4.如何解决。
instanceof 方法判断
使用:
对象名 instanceof 类名--- 》 判断前面的是否属于后面的类型。
5.封装
封装(Encapsulation):封装是指将数据和对数据的操作封装在一个单元中,通过定义类来实现。类将数据和方法封装在一起,隐藏了内部实现细节,只暴露必要的接口供外部使用。这样可以保护数据的完整性和安全性,同时提高代码的可维护性和复用性。
(之前我发布的文章中有封装具体介绍)