首页 > 技术文章 > 面向对象思想,封装,继承,构造函数,super()和this()

ct-debug 2020-05-05 14:59 原文

面向对象思想

构造器:

new就是一个构造器,作用是:①分配空间;②赋初始值(避免错误,简化输入);new Object(Parameters)构造器调用构造函数,传参为了赋初始值;

对象的基本元素:

属性和方法 类成员(属性和方法)。属性最为重要,属性的集合是一个状态,方法是一个状态到另一个状态的桥梁

封装:

属性和处理属性的方法集合起来。把数据及数据的操作方法放在一起,作为一个相互依存的整体,即对象
面向对象是基于面向过程而言的,面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节
这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。

封装

访问权限的控制常被称为是具体实现的隐藏。把数据和方法包装进类中,以及具体实现的隐藏共同被称为封装

public:可以被所有其他类访问;

protected:自身、子类、及同一个包中类(接受包外的子类访问);

default:同一包中的类可以访问,声明时没有加修饰符,认为是 friendly(拒绝一切外包访问);

private:只能被自己访问和修改。

类的访问控制符只有三种:public private protected default是无访问控制符

继承

在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象
继承使子类拥有父类所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。子类不能继承父类的构造函数,只是显式或隐式调用,可以从子类调用超类的构造函数。
new创建子类的对象时,若子类没有带参构造函数,将先执行父类的无参构造函数,然后再执行自己的构造函数。父类定义了有参的构造函数后,可以不定义无参的构造函数,系统也不会提供默认的无参构造函数。这时子类只能调用父类的有参构造函数。
Java类是单继承,Java接口可以多继承。类可以实现多个接口,接口可以继承(扩展)多个接口。先继承后实现接口。

组合和继承

组合是指在新类里面创建原有的类的对象,重复利用已有类的功能。(“has-a”)
组合和继承都允许在新的类中设置子对象,只是组合是显式的,而继承是隐式的。组合中的整体类和继承中的子类对应,组合中的局部类和继承中的父类对应。

组合和继承的选择规则:

①除非两个类之间是“is-a”的关系,否则不要轻易地使用继承。过多的使用继承会破坏代码的可维护性,当父类修改时,会影响所有继承他的子类,增加了程序维护的难度和成本。
②不要仅仅为实现多态而使用继承,如果类之间没有“is-a”关系,可以通过实现接口与组合的方式来达到相同的目的。

构造函数

用来在对象实例化时初始化对象的成员变量

特点:

①方法名必须和类名相同,不能有返回值(也不能为void
②一个类可以有多个构造函数,没有定义的话,编译器会在源代码编译成字节码文件的过程中会提供一个没有参数的默认的构造方法。若定义后,不会再创建默认的构造方法;
③构造函数的参数有(0到多个);
④构造函数在对象实例化时会被自动调用,且只运行一次;普通方法是在程序执行到时才调用且可以被该对象调用多次;
⑤构造函数的作用是完成对象的初始化;
⑥构造函数不能被继承,不能被覆盖,能被重载;
⑦子类可以通过super()关键字来显示调用父类的构造函数,父类没有提供无参构造,子类的构造函数中必须显式得调用父类的构造函数;
⑧父类和子类都没有定义构造函数时,编译器都会为父类生成一个默认的无参构造,给子类也生成一个默认的无参的构造函数;
⑨构造方法会在成员变量之后初始化;
⑩构造方法不能被static final synchronize abstract native修饰,但可以被public private protect修饰。

在继承的时候,父类当然也有构造方法,如果你要创建子类的对象,那么执行的过程首先是调用父类的无参构造方法生成父类的对象,然后再调用子类的无参构造方法来生成子类对象。继承的时候都是先生成父类的对象,然后再生成子类的对象。
通过使用 this关键字带上参数,可以在一个构造函数中调用另外一个构造函数。这是 this除了单纯表示“当前对象”(注意是针对对象而不是类的概念)之外的第二个作用。

但是注意3点:

①必须放在第一行;
②只能调用一个其它的构造函数。(也许可以这样理解,正是因为有了第一点,如果可以调用多个的话,那么就无法放在“第一行”,所以只能允许一次调用);
③只能是构造函数调用构造函数,普通函数无法调用构造函数。

super()和this()

super()关键字表示超类的意思,当前类是从超类继承而来。
this表示当前对象;

只有在重写(Override)父类的方法中,子类要调用继承自父类的方法,才使用super关键字。
使用super()或者this()方法是必须放在构造函数的第一行;
调用父类构造方法:super(参数,参数);
调用父类成员方法:super.成员方法名(参数,参数);
调用父类成员变量赋值:super.成员变量名 = 参数;

package project1;

abstract class Person {
    String name;
	int age;
	public Person(){
		System.out.println("我是空参构造方法");
	}
	public Person(String n,int a){
		name = n;
		age = a;
	}
	public void sleep(){
		System.out.println(name+"---"+age+"---"+"人都是要睡觉的");
	}
}
class Player extends Person {
	public Player(){
		super();//先调用父类空参构造方法,不向父类传递参数,再执行该构造方法的以下代码
		super.age = 19;//先向父类成员变量age赋值,再执行该构造方法的以下代码
		super.name = "张三";
	}
	public Player(String n,int a){
		super(n,a);//先调用父类有参构造方法,并向父类传递两个参数,再执行该构造方法的以下代码
	}
	public void supercy(){
		super.sleep();//先调用父类sleep成员方法,不向父类sleep成员方法传递参数,再执行该构造方法的以下代码
	}
}
package project1;

public class Dumo{
public static void main(String[] args) {
	Player p1 = new Player();
	p1.supercy();
	System.out.println("------------------------");
	Player p2 = new Player("李四",20);
	p2.supercy();
}
}

输出:

我是空参构造方法
张三---19---人都是要睡觉的
------------------------
李四---20---人都是要睡觉的

由于this函数指向的构造函数默认有super()方法,所以规定this()super()不能同时出现在一个构造函数中
因为static方法或者语句块没有实例时可以使用,而此时不需要构造实例,所以不能用this()super()

推荐阅读