面向对象的三大特征

面向对象的三大特征

继承(extends)

类是对对象的抽象,继承是对某一批类的对象,从而实现对现实世界更好的建模
提高代码的复用性(OOP)
extends的意思是”扩展”。子类是父类的扩展
例子(生物)

封装(encapsulation)/隐藏
多态(polymorphism)

继承(extends)

  • 子类继承父类(基类、超类)的属性和方法
  • 构造器不能继承!
  • 实例化子类,会递归分配所有父类的空间
  • 子类构造器一定调用父类构造器
  • 类一定有构造器(父类、子类)

继承中的语法现象 *

Java 中继承的语法现象:

  • 父类型变量可以引用子类型的实例,父类型的实现是多态的引用变量类型的自动转换(“小类型”到“大类型”的自动转换)
  • 子类可以覆盖父类的方法,修改父类的行为
  • 方法覆盖:子类覆盖了父类“相同方法签名”的方法
  • 方法的覆盖是由方法动态绑定实现的是Java 虚拟机运行时候确定执行哪个对象哪个方法,java 最终执行子类的方法
    image

方法的重写(override)

  • 在子类中可以根据需要对从基类中继承来的方法进行重写。
  • 重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
  • 重写方法不能使用比被重写更严格的访问权限
实例如下

父类

package com.neuedu.test1;
/**
 * @author wqy
 * @version 1.0
 * @since 2019/8/8
 * @apiNote 继承
 * */
public class Question {

	// 题号
	public int id;
	// 题干
	public String text;
	// 选项
	public String[] options;
	
	// 检查答案的方法 (父类的检查答案的 check()方法没有实际业务意义,检查答案都返回 false)
	public boolean checkAnswer(String[] args) {
		return false;
	}
	
	// 打印题目到控制台
	public void printText() {
		System.out.println("题号:"+id+"---题干----"+"text");
		for(int i = 0; i<options.length;i++) {
			System.out.println(options[i]);
		}
		
	}
}

子类
因为父类的 check()方法不合理(只返回 false),所以在子类中需要方法的覆盖
方法的覆盖,又叫重写(Overwrite)是根据子类的具体业务对父类方法的重写

package com.neuedu.test1;
/**
 * @author wqy
 * @version 1.0
 * @since 2019/8/8
 * @apiNote 继承
 * */
public class SingleQuestion extends Question{

	// 扩展功能 正确答案
	String answer;
	
	// 构建题号 题干 选项和正确答案
	public SingleQuestion(int id,String text,String[] options,String answer) {
		this.id = id;
		this.text = text;
		this.options = options;
		this.answer = answer;
	}

	// 方法的重写
	@Override
	public boolean checkAnswer(String[] answers) {
		
		//首先判断答案是否合法
		if(answers == null || answers.length != 1) {
			return false;
		}
		return this.answer.equals(answers[0]);
		
		
	}
}

测试类

package com.neuedu.test1;
/**
 * @author wqy
 * @version 1.0
 * @since 2019/8/8
 * @apiNote 继承
 * 测试类
 * */
public class TestQuestion {

	public static void main(String[] args) {
		String[] options = {"爱迪生" , "爱恩斯坦", "科比", "我"};
		SingleQuestion singleQuestion = new SingleQuestion(1,"世界上最好看的人是谁",options,"我");
		String[] answers = {"爱迪生"};
		boolean checkAnswer = singleQuestion.checkAnswer(answers);
		System.out.println(checkAnswer);
	}
}

继承中的构造器

子类构造器一定调用父类构造器

super()

  • 子类构造器默认调用父类无参数构造器
  • super()表示调用父类构造器
  • 使用 super()调用父类构造器,必须写在子类构造器第一行
  • this() 必须写在子类构造器第一行
  • 有 super()就不能有 this(),两者互斥

image

解决方案:显式调用父类有参构造器

image
如果父类没有无参数构造器,就必须在子类中明确指定调用父类的有参数构造器
编程建议:所有的类都提供无参数构造器!减少继承时候的麻烦

static 关键字

在类中,用static声明的成员变量为静态变量,或者叫类属性,类变量

  • 它为该类的公用变量,从属于类,被该类的所有实例共享,在类被加载时显示初始化;
  • 对于该类的所有对象来说,static成员变量只有一份,被该类的所有对象共享!!
  • 可以使用”对象.类属性”来调用。不过,一般都是用”类名.类属性
  • static变量置于方法区中
用static声明的方法为静态方法(类方法)

不需要对象,就可以调用(类名.方法名)
在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员
在普通的方法里面可以调用静态的方法和静态的属性,但是反之不能

在《Java编程思想》P86页有这样一段话:“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
方便在没有创建对象的时候调用

public class Student{
    Stirng name;
    int id;
    static int ss;
    public static void printss(){
        System.out.println(ss);
    }
    public void study(){
         System.out.println(name+"在上课");
    }
    public void sayHello(String sname){
         System.out.println(name+"向"+sname+"说你好!");
    }
}
//新建个测试static类
public class TestStatic{
    public static void main(String[] args){
        Student.ss = 121;
        Student.printSS();
    }
}

static关键字、语句块练习

执行优先级:静态代码块 > main方法 > 构造代码块 > 构造方法

image
image

访问控制修饰符

Java 中的访问控制符,是修饰 Java 中类、属性、方法的访问可见范围的。请记住如下表格
image
注:

  • public 修饰的,在任何地方都能访问
  • protected 修饰的,在类内部、同一个包、子类中能访问
  • [default]修饰的,在类内部和同一个包中可以访问,默认的,不可以写出来
  • private 修饰的,仅限当前类内部访问
    访问控制的原则:尽可能的封装

private 修饰的属性,仅限本类内部访问

image
注:

  • 第 9 行,编译错误,private 修饰的属性不能在 Foo 外部调用
  • 第 10 行,getA()方法是 public 的,供外界调用,间接读取了 d 的值
  • 第 18 行,d 设置为 private 后,相当于只读的

[default]类内、同包下能访问,不同包不能访问

image

protected 修饰的,在类内部、同一个包、子类中能访问

image
知识点小结:

  • 方法也可以用访问控制符修饰,一般为 private 的表示只在类内部调用,外部不可见
  • 声明属性和方法尽可能私有。这样才能做到尽可能的封装
  • 提供适当的属性访问方法,适当的开放属性的访问
  • 一个源文件可以有多个类, 但是只能有一个public 类, 文件名要与public 类一致. 如果有其他类, 就只能是默认[default]修饰
  • 不建议使用非公有类。就是说所有类都应该是公有的,并且一个源文件一个类.

Object类

Object类是所有Java类的父类
如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类

public class Person{                
     
}
class Person extends Object{
    //可以省略不写
}

重写toString方法

  • 默认返回:包名+类名+@+哈希码 ->根据对象内存位置生成唯一不重复
  • 可以重写
  • 打开API文档,开始熟悉

final关键字

final关键字修饰的类、变量、方法具有以下特征

  • 修饰变量:常量,不能被二次赋值,只能初始化时给值或者在构造方法中给值。一般final与static同用,方便静态方法直接调用
  • 修饰方法:
    该方法不可被子类重写。但是可以被重载!
  • 修饰类(String类):
    修饰的类不能有子类,不能被继承。比如:Math、String
  • 修饰引用数据类型时,引用数据类型的地址不可改变,引用数据类型中的内容可以改变,修饰基本数据类型时,基本数据类型的值不可以改变
public class TestFinal{
    public static void main(String[] args){
        final int MAX_VALUE = 200;//常量
    }
}


//测试重载
public /*final*/ class Animal {//final修饰类则说明,这个类不能被继承
    public /*final*/ void run(){//final加到方法前,一位值该方法不能被子类重写!
        System.out.println("我能跑");
    }
}       
class Bird extends Animal{
    public void run(){
        System.out.println("我能飞!");
    }
}

引用类型转换

向上转型(隐式/自动类型转换),是小类型到大类型的转换
向下转型(强制类型转换),是大类型到小类型
instanceof 运算符,用来检查引用对象的类型
经常与"引用类型强制转换"配合,实现安全的类型转换,避免类型转换异常
  • 向上转型(隐式/自动类型转换)
    image
  • 向下转型(强制类型转换),是大类型到小类型
    image
    image

JavaBean规范

在 Java 中将这种建议的规范总结出一套,我们称之为“JavaBean 规范”.
关于 JavaBean 规范:JavaBean 不是语法规范,是习惯性编程规范,用这个规范写的类使用方便.
有时候 JavaBean 的类也称为:POJO 类(Plan Old Java Object)
简化规范:

  • 必须有包(package)
  • Java 类,具有无参数构造器
  • 有用 getXxx() 和 setXxx() 声明的 Bean 属性
  • 必须实现序列化接口(注:在学习 IO 的时候具体学习)
    JDK 提供的类几乎都符合 JavaBean 规范。如:String 类, 集合类
    JavaBean 最大的好处:使用方便

垃圾回收器GC

  • 程序员无权调用垃圾回收器
  • 程序员可以通过System.gc();通知GC运行,但是java复返并不能保证立刻运行
  • finalize()方法,是java提供给程序员用来释放对象或者资源的方法,但是尽量少用。

多态

简单来说:一种事物,多种形态

所谓多态,就是指同一个方法,在调用的过程中由于对象不同可能会有不同的行为.现实生活中,同一个行为,具体实现会完全不同
具有表现多种形态的能力的特征
同一个实现接口,使用不同的实例而执行不同操作
举个例子: 打印机

父类

public class Print {

	// 打印的方法
	public void printer() {
		System.out.println("打印。。。");
	}
	
}

子类

public class BlackAndWhitePrinter extends Print {

	@Override
	public void printer() {
		System.out.println("黑白打印。。");
	}
}

子类

public class ColorfulPrinter extends Print {

	@Override
	public void printer() {
		System.out.println("彩色打印。。。");
	}	
}

测试类

package com.neuedu.test5;

/**
* @ClassName: PrintTest
* @Description: 多态测试类
* @author wqy
* @date 2019年8月13日 上午10:55:06
*
*/
public class PrintTest {

	public static void main(String[] args) {
		// 黑白打印
		BlackAndWhitePrinter bawp = new  BlackAndWhitePrinter();
		bawp.printer();
		// 彩色打印
		ColorfulPrinter cfp = new ColorfulPrinter();
		cfp.printer();
		
		// 多态 (实现多态的三个必要条件)
		// 继承 重写 向上转型(子类转父类,用父类接收)
		// 赋值多态 调用的new后边的子类的方法
		Print printer = new BlackAndWhitePrinter();
		printer.printer();
		
		//传参多态
		ColorfulPrinter cfp1 = new ColorfulPrinter();
		toPrint(cfp1);
		
	}
	// 定义方法要打印(传参多态)
	public static void toPrint(Print printer) {
		printer.printer();
	}
}
实现条件:

Java实现多态有三个必要条件:继承、重写、向上转型.
实现形式:
在Java中有两种形式可以实现多态。继承和接口.

多态优点:
  1. 简化代码
  2. 改善代码的组织性和可读性
  3. 易于扩展

封装

隐藏对象的属性和实现细节

对自己的变量私有化,提供公开的接口让别人去访问,按照提供的公共的方法来访问

通过 访问修饰符 来控制 是否要被访问

私有访问权限:private
  • 使用 private 关键字来修饰成员变量。
  • 对需要访问的成员变量,提供对应的一对 getXxx 方法 、 setXxx 方法.
公有访问权限:public
  • 封装提高了数据的安全性
    别人不能够通过 变量名.属性名 的方式来修改某个私有的成员属性
  • 操作简单
    封装后,多个调用者在使用的时候,只需调用方法即可,调用者不需要再进行判断
  • 隐藏了实现
    实现过程对调用者是不可见的,调用者只需调用方法即可,不知道具体实现过程
### Python 面向对象编程的三大特性 #### 1. 封装 封装是一种将数据(属性)和行为(方法)绑定到一起的技术,通过访问控制来隐藏内部实现细节。在 Python 中,可以通过使用私有属性(以双下划线开头 `__` 的变量名)来限制外部直接访问这些属性[^2]。为了操作这些私有属性,通常会提供公共接口,即 getter 和 setter 方法,分别用于读取和设置私有属性的值。 以下是封装的一个简单示例: ```python class Person: def __init__(self, name, age): self.__name = name # 私有属性 self.__age = age # 私有属性 def get_name(self): # 获取私有属性的方法 return self.__name def set_age(self, age): # 设置私有属性的方法 if age >= 0: self.__age = age else: raise ValueError("年龄不能为负") person = Person("Alice", 30) print(person.get_name()) # 输出 Alice person.set_age(35) # 修改年龄 ``` #### 2. 继承 继承是面向对象编程的核心特性之一,它允许创建一个新的类(子类),基于已有的类(父类)进行扩展或修改。这样可以减少重复代码并提高代码的可维护性和复用性[^3]。在 Python 中,默认情况下所有的类都继承自 `object` 类[^5]。 下面是一个简单的继承例子: ```python class Animal: def speak(self): return "动物发出声音" class Dog(Animal): def speak(self): # 覆盖父类方法 return super().speak() + ", 狗吠叫" dog = Dog() print(dog.speak()) # 输出 动物发出声音, 狗吠叫 ``` #### 3. 多态 多态是指同一个方法调用可以在不同的对象上表现出不同形式的能力。这种能力使得程序设计更加灵活,因为相同的接口可以根据实际的对象类型执行不同的逻辑[^4]。在 Python 中,由于其动态类型的特性,多态表现得尤为自然。 以下展示了如何利用多态处理不同类型的对象: ```python class Cat: def sound(self): return "喵呜" class Bird: def sound(self): return "叽喳" def make_sound(animal): print(animal.sound()) cat = Cat() bird = Bird() make_sound(cat) # 输出 喵呜 make_sound(bird) # 输出 叽喳 ``` --- ### 总结 Python 的面向对象编程支持封装、继承和多态这三种核心特性。它们共同作用于构建复杂而高效的软件系统,其中封装提供了安全性,继承促进了代码重用,多态增强了灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值