Java三大特征:封装、继承与抽象类

  • Post author:
  • Post category:java





1、封装



1.1 概念

对类隐藏内部执行代码与数据细节,提供公开简单方式进行使用。

  • 方法的封装:将多行执行代码封装成方法使用方法名进行标识使用
  • 类的封装:将书写与方法封装为类。为指定的类创建对象提供属性与行为
  • 但是,现在的封装指的最多的是对属性的封装,使用private对象属性进行修饰使其只对当前类可见,提供公开的方法进行访问


最终:

使用访问权限修饰符对属性进行封装,使其只对可见类进行访问,大大的提高了系统的安全性



1.2 封装的原则



属性

隐藏起来,若需要访问某个属性,提供

公共方法

对其访问。



1.3 如何封装

  • 使用

    private

    关键字来修饰成员变量。

  • 对需要访问的成员变量,提供对应的一对

    getXxx

    方法 、

    setXxx

    方法。



1.4 访问权限修饰符

用于修饰类、成员变量、方法的关键字,用于设置其使用范围(可见性)


  • public

    公共的

  • 空格

    默认,如果没有书写访问权限修饰符,系统会默认添加

  • protected

    受保护的

  • private

    私有的,只有当前类的方法才能够访问


修饰类

  • 只能使用默认或者public(一般用public)
  • 默认是当前类以及当前包下其他类可用,类如果是私有的只有当前类能用,那么就没有意义


修饰变量

  • 可以使用任意访问权限修饰符进行修饰(一般使用private)
  • 只能用于成员变量

修饰方法

  • 可以使用任意访问权限修饰符进行修饰(一般使用public)
  • 因为方法执行方法体书写可以进行逻辑书写,所以一般除核心方法不会进行私有
  • 如果书写私有方法 那么在当前类其他方法中一定调用



1.5

private

关键字

  • 什么是

    private

    关键字
	1. private是一个权限修饰符,代表最小权限。 
	2. 可以修饰成员变量和成员方法。 
	3. 被private修饰后的成员变量和成员方法,只在本类中才能访问

  • private

    的使用格式
		private 数据类型 变量名 ;
  • 使用

    private

    修饰成员变量
		public class Student { 
   			private String name;
    		private int age; 
		}
  • 提供

    getXxx

    方法 /

    setXxx

    方法,可以访问成员变量
		public class Student {
			private String name;//属性私有化
			private int age;
	
			//提供公开的getter  setter方法
			//用于外部其他类通过方法进行属性的操作
			public void setName(String n){
				name=n;
			}
			public void setAge(int a){
				if(a==18){
					System.out.println("臭不要脸");
				}else{
					age=a;
				}
			}
	
			public String getName(){
				return name;
			}
			public void say(){
				System.out.println("我叫"+name+",今年"+age);
			}
		}



1.6

this

关键字



1.6.1

this

的含义

this代表所在类的当前对象的引用(地址值),即对象自己的引用。


  • this

    中保存的是调用对象的内存地址。


记住 :方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁。



1.6.2

this

的使用格式

this.成员变量名;

this.方法;



1.6.3 代码书写

		public class Student {
    		private String name;
    		private int age;

    		public void setName(String name) {    //name = name;
        		this.name = name;
    		}

    		public String getName() {
        		return name;
    		}

    		public void setAge(int age) {
        		//age = age;
        		this.age = age;
    		}

    		public int getAge() {
        		return age;
    		}
		}



2、构造方法



2.1 构造方法的概述

又称之为构造函数、构造器,在使用new关键字创建对象时,由jvm调用根据传入的参数创建对象并对属性进行赋值。

  • 作用:创建对象并进行初始化赋值


小贴士:

无论你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个无参数构造方法,一旦自己定义了构造方法,Java自动提供的默认无参数构造方法就会失效。



2.2 构造方法的定义格式

		修饰符 构造方法名(参数列表){ 
    		// 方法体 
		}
  • 修饰符多为public
  • 无返回值(void也没有)
  • 方法名固定(类名)
  • 参数列表已知(属性)
  • 方法体多为赋值



2.3 构造方法的使用与重载

构造方法虽然与普通方法存在区别,但是也可以实现方法的重载,只不过由于构造方法执行的特点,所以构造方法重载,一般指的是参数个数不同

		class People {
			private String name;
			private boolean alive=true;
			private String oldName;

			public People(String name){
				this.name=name;
			}

			public People(String name,boolean alive){
				this.name=name;
				this.alive=alive;
			}
		}



2.4 构造方法的特点

① 构造方法没有返回值

② 构造方法的方法名就是类名

③ 所有的类都有构造方法,如果在代码书写中没有显式定义构造方法,那么在编译时jvm会自动添加一个无参构造方法

④ 如果类中书写了任意构造方法,那么不会在提供无参构造方法



2.5 构造方法的注意事项

  1. 如果你不提供构造方法,系统会给出无参数构造方法。
  2. 如果你提供了构造方法,系统将不再提供无参数构造方法。
  3. 构造方法是可以重载的,既可以定义参数,也可以不定义参数。



3、标准JavaBean编写

JavaBean 是 Java语言编写类的一种标准规范。符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的 set 和 get 方法。



3.1 概念

JavaBean:在Java中用于存储数据或描绘对象的类



3.2 书写

//计算机类
		public class Computer {
	
			//属性
			private String manufacturer;//厂商
			private double price;//价格
			private String color;//颜色
			private int size;//尺寸
	
			//构造方法的书写
			//使用默认构造方法有时不能满足需求
	
			//无参构造方法
			public Computer(){}
			//全参构造方法
			public Computer(String manufacturer,double price,String color,int size){
				this.manufacturer=manufacturer;
				this.price=price;
				this.color=color;
				this.size=size;
			}
			//其余构造方法根据实际需求进行创建
	

			//封装对属性使用private修饰符
			//提供公开的getter setter方法
			public void setManufacturer(String manufacturer){
				this.manufacturer=manufacturer;
			}
			public String getManufacturer (){
				return manufacturer;
			}

			public double getPrice() {
				return price;
			}
			public void setPrice(double price) {
				this.price = price;
			}
			public String getColor() {
				return color;
			}
			public void setColor(String color) {
				this.color = color;
			}
			public int getSize() {
				return size;
			}
			public void setSize(int size) {
				this.size = size;
			}
			//行为
			public void open(){
				System.out.println(size+"寸的"+manufacturer+"电脑开机了");
			}
			public void close(){
				System.out.println(color+"颜色的"+manufacturer+"电脑关机了");
			}
		}



4、继承



4.1 概念

子类继承父类,继承父类非私有的属性与方法

在这里插入图片描述

继承描述的是事物之间的所属关系



4.2 特点

  • Java中的继承是单继承(一个子类只能拥有一个父类,但是一个父类可以拥有多个子类)
  • 继承关键字书写在子类
  • 子类可以继承父类非私有的属性与方法
  • 子类可以书写额外的属性与方法
  • 类与类之间产生了关系,是

    多态的前提



4.3 书写

在Java书写过程中两个类之间的关系使用关键字进行设置,在子类中通过

extends

关键字设置当前类继承的父类。

		class 子类 extends 父类 { ... }
		/** 
		定义员工类Employee,做为父类
		 */
		class Employee {
    		String name; // 定义name属性
    		// 定义员工的工作方法
    		public void work() {
        		System.out.println("尽心尽力地工作");    }
			}

		/*
		 * 定义讲师类Teacher 继承 员工类Employee
 		*/
		class Teacher extends Employee {
  		  	// 定义一个打印name的方法
   			public void printName() {
        		System.out.println("name=" + name);    }
			}

		/*
 		* 定义测试类
 		*/
		public class ExtendDemo01 {
    		public static void main(String[] args) {       
        		// 创建一个讲师类对象
        		Teacher t = new Teacher();

        		// 为该员工类的name属性进行赋值
        		t.name = "小明"; 

        		// 调用该员工的printName()方法
        		t.printName(); // name = 小明

        		// 调用Teacher类继承来的work()方法
        		t.work();  // 尽心尽力地工作
    		}
		}



4.4 继承中成员的访问



4.4.1 成员变量的访问


  • 成员变量不重名

如果子类中没有与父类相同的属性,那么在使用时使用父类的属性。

		public class FatherTest{
			public static void main(String[] args) {
				Son s=new Son();
				s.name="使用父类name属性进行数据存储";
				System.out.println(s.name);
			}
		}
		class Father {
			public String name;

		}

		class Son extends Father{
	
		}

  • 成员变量重名

如果子类中有与父类相同的属性(在继承中一般不这样书写)

		public class FatherTest{
			public static void main(String[] args) {
				Son s=new Son();
				s.name="使用自己的属性进行存储";
			}
		}
		class Father {
			public String name;

		}

		class Son extends Father{
			public String name;
		}
  • 在子类继承父类后,如果子类拥有相同的属性那么在使用时,默认使用子类的属性,方法也是一样。



4.4.2 成员方法的访问


  • 成员方法不重名

如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。

		class Fu{
    		public void show(){
        		System.out.println("Fu类中的show方法执行");    }
		}
		class Zi extends Fu{
    		public void show2(){
        		System.out.println("Zi类中的show2方法执行");    }
		}
		public  class ExtendsDemo04{
    		public static void main(String[] args) {
        		Zi z = new Zi();
        		//子类中没有show方法,但是可以找到父类方法去执行
        		z.show();        
        		z.show2();    
    		}
		}

  • 成员方法重名(方法的重写Override)

如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做

方法重写(Override)

在继承过程中,子类继承父类方法,父类方法不满足子类需求,子类重写父类方法方法体,实现方法的重写。


方法重写:

子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。


方法重写的要求:

修饰符访问范围大于或等于父类 返回值不能修改 方法名不能修改 参数列表不能修改 方法体根据需求修改。


@Override

:重写注解,无特殊功能,用于标识重写的方法,被该注解标识的方法必须满足方法重写的语法规则。

		public class FatherTest{
			public static void main(String[] args) {
				Son s=new Son();
				s.eat();
			}
		}
		class Father {
			public String name;
			public void eat(){
				System.out.println("爸爸会吃饭");
			}
		}

		class Son extends Father{
			public String name;
			//子类重写父类方法 修改方法体  执行默认执行子类方法
			@Override
			public void eat(){
				System.out.println("儿子会吃饭");
			}
		}



面试题




override与overload的区别



  • overload:

    方法重载

    在一个类,方法名相同参数列表不同称发生了方法的重载,或多个方法互为重载


    仅有返回类型不同是不足以区分两个重载的方法。



    参数列表不同:

    1. 参数个数不同 ==> 两个方法 方法名相同 参数列表个数不同
    2. 参数数据类型不同 ==> 两个方法 方法名相同 参数列表个数相同 参数类型不同
    3. 参数顺序不同 ==> 两个方法 方法名相同 参数列表个数相同 参数类型相同(个数类型两个以上) 参数数据类型的顺序不同

  • override

    :方法重写

    发生继承过程中,子类重写继承父类方法,称之为重写。

  • overload和override的区别:




    发生位置不同:

    重载一般发生在同一类中,重写发生在继承中



    书写语法不同:

    重载只需要方法名与参数列表就可以发生,重写返回值、方法名、参数列表必须与父类相同



4.5 继承-数据存储的原理

子类在创建时,只会根据当前子类拥有的属性开辟内存空间存储对应数据,在程序执行中在创建子类时首先都会创建一个与之唯一对应的父类对象(子类构造方法第一行调用父类构造方法),在进行存储时,如果存储子类没有的属性,实际上是存储到了与之相对应的父类对象中。

		public class FatherTest{
			public static void main(String[] args) {
				Son s=new Son();
				s.name="儿子";
				s.eat();
			}
		}
		class Father {
			public String name;
			public Father(){
			}
			public void eat(){
				System.out.println("爸爸会吃饭");
			}
		}
		class Son extends Father{
			//子类重写父类方法 修改方法体  执行默认执行子类方法
			@Override
			public void eat() {
				super.eat();
				System.out.println(super.name+"会吃饭"+this.name);
			}
		}

在这里插入图片描述



4.6

super

关键字

所有的类都有父类,如果书写了关键字继承父类 那么指定的父类就是其父类,如果一个类没有书写父类那么默认继承Object(基类 超类)


super

代表父类

在进行变量与方法执行时,如果子类拥有与父类相同的变量与方法,那么默认会调用子类的,如果想获取执行父类的变量与方法需要使用super关键字进行标识。

		this.成员变量       ‐‐    本类的
		super.成员变量      ‐‐    父类的

		this.成员方法名()    ‐‐    本类的    
		super.成员方法名()   ‐‐    父类的

在子类中,子类构造方法会默认调用父类无参构造方法,创建父类对象,并且子类构造方法调用父类构造方法的语句必须书写在子类构造方法的第一行。



面试题




this与super关键字的区别


  • this:当前类中方法声明的形参与成员变量相同时,使用this关键字标识成员变量
  • super:在继承过程中子类属性方法与父类属性方法相同时,使用super关键字标识父类属性与方法
  • this与super都可以调用构造方法
  • super()和this()都必须是在构造方法的第一行,所以不能同时出现。



5 抽象类

本质还是一个类,在类的书写过程中如果存在由于类的定义无法实现的方法时,将方法定义为抽象方法,同时将类定义为抽象类。



5.1 概念

父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。



5.2 抽象类与抽象方法的书写

使用

abstract

关键字对类与方法进行修饰,被其修饰的类称之为抽象类,方法称之为抽象方法

一个类如果有抽象方法,那么这个类一定是抽象类,如果一个类是抽象类不一定拥有抽象方法

  • 抽象方法的格式
		修饰符 abstract 返回值类型 方法名 (参数列表);
		public abstract void run();
  • 抽象类的格式
		public abstract class 类名字 {   
		}
		
		public abstract class Animal {
    		public abstract void run();
		}
		//图形类
		public abstract class Figure {
			//计算周长
			public abstract void zc();
			//计算面积
			public abstract void mj();
		}

可以理解为,当书写的类过于抽象,并且其中的方法方法体无法实现时,使用抽象类。



5.3 抽象的使用

继承抽象类的子类

必须重写父类所有的抽象方法

。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父类所有的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。

			public abstract class Animal {
    			public abstract void run();
			} 

			public class Cat extends Animal {
    			public void run (){
        			System.out.println("小猫在墙头走~~~")}
			}

			public class CatTest {
    			public static void main(String[] args) {
        			// 创建子类对象
        			Cat c = new Cat(); 

        			// 调用run方法
        			c.run();
    			}
			}

此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。



5.4 抽象的注意事项

  • 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  • 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。

    理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

  • 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  • 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。



每日一点点进步



不进则退



版权声明:本文为qq_43492477原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。