Java面向对象

(前言)Java 和 C++ 的区别?

  • 都是面向对象的语言,都支持封装、继承和多态
  • Java 不提供指针来直接访问内存,程序内存更加安全
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
  • Java 有自动内存管理机制,不需要程序员手动释放无用内存
  • 在 C 语言中,字符串或字符数组最后都会有一个额外的字符‘\0’来表示结束。但是,Java 语言中没有结束符这一概念。 这是一个值得深度思考的问题,具体请看这篇文章。

面向对象

构造器

构造器类似于C++语言中的构造函数,

构造器的结构:

​ 1.和类名相同

​ 2.没有返回值

作用:

1. new 的本质是在调用构造方法

2. 初始化对象的值

注意:在定义了有参构造之后,若想使用无参构造,必须显式的定义一个无参的构造(和C++中的有参构造函数和无参构造函数基本相同)。

public class demo1 {
	String name;
    //无参构造
	public demo1() {
		
	}
    //有参构造
	public demo1(String name) {
		this.name = name;
	}
}

在调用构造函数时,只能通过 new 的方法调用:

类名 + 对象名 = new 类名();
如:
   	Student student = new Student();
	student.name = xxx;

封装

封装的好处:

​ 1.提高程序的安全性,保护数据

​ 2.隐藏代码的实现细节

​ 3.统一接口

​ 4.提高系统的可维护性

封装的方法:

属性私有(private),get / set

private int age;
	public static void main(String[] args) {
		
	}
	//set:设置
	public int setAge(int age) {
			this.age = age;
			return this.age;
	}
	//get:读取
	public int getAge() {
		return this.age;
	}

继承

继承的本质是对某一批类的抽象,关键字为 extends 。比如 A 类继承了 B 类,我们就写成

class A extends B(){
    
}

继承是子类继承父类,我们也可以理解是 “is a” 的关系,比如:旺财是一只狗,旺财相当于子类,狗相当于父类,子类继承了父类的所有属性。

Java 中类只有单继承,没有多继承! 可以这样理解:一个儿子只能有一个爸爸,而一个爸爸可以有多个儿子

所有的类都默认继承了 Object 类,如果 A 类继承了 B 类,那么 Object 就是 A 类的祖父类。也就是说,一个类只能直接继承一个类,而可以间接继承多个类。

private 和 protected 的区别

privateprotected 修饰的属性外界都不能直接访问,但 protected 修饰的属性其子类是可以调用的,而 private修饰的属性除了自身任何人都访问不了:

可以通过 super 来访问父类中 protected 修饰的属性。

public class Person {
	protected String name;
    private int age;
	public static void main(String[] args) {
		
	}
}
public class Student extends Person{
	public static void main(String[] args) {
		Student stu = new Student();
		System.out.println(super.name);
        System.out.println(stu.age);	//error
	}
}
super关键字

调用父类的构造器:super(); ,当调用子类的构造器时系统会默认先调用父类的构造器,如果要显式写出 super(); 必须在子类构造器的第一行。

public Student() {
//		super();//默认就有的,作用是调用父类的无参构造器,若要显式写出,必须写在子类构造器的第一行
//		super(xxxx);//调用父类的有参构造器,必须显式写出
		System.out.println("Student的无参构造");
	}

当父类里面写了有参构造时,不论是父类还是子类要想调用无参构造都必须显式的写出无参构造,否则会出错。

super 注意点:

  • super 调用父类的构造方法,必须写在构造方法的第一行。
  • super 必须只能出现在子类的方法或者构造方法中。
  • super 和 this 不能同时调用构造方法!即super ();this (); 不能同时出现在一个函数中。

继承的几个要点:

  1. 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有
  2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  3. 子类可以用自己的方式实现父类的方法。(重写)

重写

重写:需要有继承关系,子类重写父类的方法!重写是指方法重写,和属性无关!

为什么需要重写:当子类需要使用父类的一些功能,而子类需要增加新的功能,可以通过重写实现。在实际开发过程中,如果改变父类的方法,父类的所有子类也会被改写,造成麻烦,所以我们使用重写来避免这一情况。

重写的特点:

1.方法名必须相同

2.参数列表必须相同

3.修饰符:子类的访问权限必须不能比父类小 *访问权限:*public > protected > default > private

4.抛出的异常范围可以被缩小,但不能扩大

5.父类私有的方法,子类不能进行方法重写

重写:子类的方法和父类必须要一致,方法体不同!

无法重写的方法:

1. **static 方法,属于类,不属于实例**

2. **final 常量池**
3. **private 方法**

方法重写和方法重载的区别:

  • 方法重写:子类和父类中方法相同,两个类之间的关系,函数的返回值类型、函数名、参数列表都一样
  • 方法重载:指在同一个类中,多个方法名相同,他们的参数列表不同(个数不同,数据类型不同)

对比 this :

代表的对象不同:

this : 本身调用者这个对象

super : 代表父类对象的引用

前提:

this : 没有继承也可以使用

super : 只有在继承条件才可以使用

构造方法:

this () ; 本类的构造

super () ; 父类的构造

多态

父类的引用变量指向子类对象:

父类类型 变量名 = new 子类类型();
变量名.方法名();

Person per = new Student();
per.xxxx();

对象能执行哪些方法,主要看左边,和右边关系不大!

Person per = new Student();
Student stu = new Student();

如果要调用的方法左边的类没有,就调用失败。若子类重写了父类的方法,就调用子类重写后的方法。

上述代码中:

Student 是子类,能够调用自身或者继承父类的方法。

Person 是父类,只能够调用自身的方法,不能调用子类独有的方法。

如果父类想要调用子类的方法(父类转换成子类),以上面为例,Person 想要调用 Student 的一些独有的方法,就需要类型转换这一操作:

Person per = new Student();
((Student) per).go();
((Student) per).run();

子类如果想要转换为父类(向上转型)

父类转换为子类(向下转型):强制转换

多态成员的特点
  • 成员变量在编译时,参考的是引用类型所属的类(父类)中是否有被调用的成员变量。没有则编译失败。

  • 成员变量在运行时,参考的也是引用类型所属的类(父类)中是否有被调用的成员变量。没有则运行失败。

    即:成员变量编译和运行都是看等号的左边(父类)

  • 成员方法编译时,参考引用变量所属的类(父类),如果类中没有调用的方法,编译失败

  • 成员方法运行时,参考引用变量所指的对象所属的类(子类),并运行对象所属类中的方法
    即:成员方法编译看左边(父类),运行看右边(子类)

    //创建父类
    public class Fu {
        int num = 1;    //定义成员变量
        public void fun()   //定义成员方法
        {
            System.out.println("父类");
        }
    }
    //创建子类
    public class Zi extends Fu {
        int num = 2;
        public void fun()
        {
            System.out.println("子类");
        }
    }
    //main中调用
    public class Main {
        public static void main(String[] args)
        {
            Fu f = new Zi();
            System.out.println(f.num);      //成员变量编译和运行都是参考父类的
            f.fun();        //成员方法编译参考父类,运行参考子类
        }
    }
    

    运行结果:

    1
    子类
    

多态注意事项:

​ 1.多态是方法的多态,属性没有多态

​ 2.必须有父子类关系或类实现接口关系

​ 3.存在的条件:有继承关系,方法需要重写,父类引用指向子类对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值