首页 > 其他分享 >07.面向对象

07.面向对象

时间:2024-11-29 10:44:06浏览次数:6  
标签:07 构造方法 子类 void 面向对象 父类 方法 public

面向对象

面向对象编程的本质

以类的形式组织代码,以对象的形式封装(组织)数据。

static

   public void a(){
		b();
    }
    public static void b(){
        a();//错误
    }
}

static和类一起加载,其他实例化才会加载。

构造器

new对象时候,本质是在调用构造器

无参构造:默认会提供无参构造。

有参构造:一旦构造了有参构造,无参构造必须显式定义。4

alt+insert生成构造器

内存分析

!image-20241121163058300

类方法和实例方法

1. 类方法——用static修饰的方法。
由于类方法是属于整个类的,不属于类的某一个实例(对象)
即类方法体有如下限制:
1.类方法中不能引用实例变量;
2.类方法中不能调用类的实例方法;
3.在类方法中不能调使用super,this关键字;
4.类方法不能被覆盖。

2.实例方法
实例方法
当一个类创建了一个对象后,这个对象就可以调用该类的方法(对象方法)。
1.实例方法中可以引用实例变量,也可以引用类变量;
2.实例方法中可以调用类方法;
3.对象方法中可以使用super,this关键字。

3.区别

1.类方法可以通过类名调用,实例方法不能通过类名调用

2.静态内存是连续的,因为是在程序开始时就生成了,而实例申请的是离散的空间,所以当然没有静态方法快,而且静态内存是有限制的,太多了程序会启动不了。类方法常驻内存,实例方法不是,所以类方法效率高但占内存

3.类方法不可被继承,因此子类中相同名字的类方法不能覆盖父类的类方法(?)

this和super

概念

this关键字用于指代当前对象实例本身。在Java中,当你创建一个类的实例(对象)时,this就是指向这个实例的引用。

用法

  1. 在构造方法中使用this,代表使用该构造方法创建的对象。

  2. 在实例方法中使用this,代表使用该方法的对象。

  3. 区分成员变量和局部变量:

    如果在方法内局部变量的命名与实例变量的命名相同,根据内部屏蔽外部的原则,实例变量(外部调用)在这个方法内暂时失效。如果想在该方法中使用实例变量,则需要在变量名前显示的加上"this."用来指明此变量是实例变量。

void setleg(int leg){
		this.leg = leg; //此处利用this区分了实例变量与局部变量。
	}
  1. 类方法中不能使用this

​ 类方法(或有static修饰的静态方法)中不能使用this关键字。因为这些方法是静态的,常驻内存。当程序执行,为这些方法在内存中开辟存储空间的时候,可能还没有任何对象诞生。this关键字也就失去了意义。

概念

super关键字用于从子类中访问父类的内容。当你创建一个子类对象时,它同时也包含了父类的所有内容(成员变量、成员方法等),super就是指向这个父类内容的引用。

用法

  • 访问父类的成员变量:
    如果子类覆盖了父类的成员变量,我们可以使用super来访问父类的成员变量。
  • 调用父类的成员方法:
    如果子类覆盖了父类的方法,我们可以使用super来调用父类的方法。
  • 调用父类的构造方法:
    在子类的构造方法中,我们可以使用super(…)来调用父类的构造方法。

区别

  • this引用的是当前对象本身,可以用来访问当前对象的成员变量、成员方法或返回当前对象本身。

  • super引用的是当前对象的父类对象,可以用来访问父类的成员变量、成员方法或构造方法。

  • 在构造方法中,this(…)用于调用当前类的其他构造方法,而super(…)用于调用父类的构造方法。注意,这两者在构造方法中必须是第一条语句。

  • this和super都不能在静态方法、静态代码块或类变量声明中使用,因为它们都依赖于具体的对象实例。

使用this关键字来调用本类中构造方法

  // 无参数的构造方法
public Person() {
    this("Unknown", 0); // 调用带两个参数的构造方法
}
// 带一个参数的构造方法
public Person(String name) {
    this(name, 0); // 调用带两个参数的构造方法
}

// 带两个参数的构造方法
public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

通过使用this关键字,我们可以减少代码的重复,并确保所有构造方法都正确地初始化对象。这是实现构造方法重用的一种常见方式。

封装

private:私有

属性私有,get/set

继承

定义

对一批类的抽象。

子类继承父类,用extends关键字。

所有类默认继承Object类。

一个类只可以直接继承一个父类,可以间接继承多个父类。(单继承)

super()和this()

super注意点:

  1. super调用父类构造方法,必须在构造方法的第一个;

  2. super和this不能同时调用构造方法;

this():本类构造

super():父类构造

构造器

public Student(){
	super();//默认隐藏
	SYstem.out.println("无参构造");
}

重写

需要有继承关系,子类重写父类方法

  1. 方法名完全相同
  2. 参数列表必须相同
  3. 修饰符范围可以扩大:public>protected>default>private (静态无法重写)
  4. 抛出的异常:范围可以被缩小,不能扩大;(异常范围不能大于父类)
//静态方法和非静态方法区别很大!
//没有static时,b调用的对象的方法(没有B类静态方法),而B是使用A类new的
//有static时,b调用了B类的方法,因为b是用B类定义的
//因为静态方法是类的方法,而非静态是对象的方法。
//省流:先看左侧定义数据类型,若有静态方法则为静态方法调用,若无则为右侧对象方法


//方法的调用只和左边定义的数据类型有关
A a =new A();
a.test();//A-test

//父类的引用指向了字类
B b=new A();
b.test();//A-test
public class A extends B{
    @Override//重写
	public void test(){
		system.out.println("A-test");
	}
}
public class B{
	public void test(){//没有static
		system.out.println("B-test");
	}
}

为什么重写?

父类功能子类不一定需要/不满足;

多态

用法

一个对象的实际类型是确定的,但是可以指向的引用类型不确定。如下:

Student s1=new Student();
Person s2=new Student();//父类的引用 指向 子类对象
Object s3=new Student();
public class Person {
    public void run(){
        System.out.println("run");
    }
}
public class Student extends Person{
    public void run(){
        System.out.println("studentnrun");//子类重写父类方法
    }
}
public class Application {
    public static void main(String[] args) {
        //调用自己的或者父类的
    Student s1=new Student();
        //可以指向子类,但是不能调用子类独有的方法    
    Person s2=new Student(//父类的引用 指向 子类对象。 若子类没有重写,则使用父类。若子类重写,使用子类。保证程序执行时候才知道结果如何,动态,灵活
        											  //若子类有方法而父类没有,则报错。(除非强制转换(Student)s2).eat())

    s1.run();//Student run
    s2.run();//Student run 字类重写父类方法,执行子类。
    }
}

注意事项:

  1. 多态是方法的多态,没有属性多态
  2. 父类和字类,有联系
  3. 子类重写父类方法,使用子类 父类引用指向子类对象 father f1=new Son();

方法不可重写:

  • static 属于类,不属于实例
  • final 常量
  • private方法

instance of

X instanceof Y 
image-20241121202504721

能不能编译通过!看‘=’左边类型与instanceof后面的类型是否是继承关系。运行结果是true还是false,看‘=’右边与instanceof后面的类型是否是继承关系

Fu f = new Zi();//拥有了被Zi类函数覆盖后的Fu类对象----f------。

所以f所代表的是函数被复写后(多态的意义)的一个Fu类,而Fu类原来有的成员变量(不是成员函数不可能被复写)没有任何变化。

获得结论:

1、成员变量:编译和运行都看Fu。

2、非静态方法:编译看Fu,运行看Zi

3、静态方法:编译和运行都看Fu。

其实很简单,首先我们要理解静态情况下发生了什么?当静态时,Fu类的所有函数跟随Fu类加载而加载了。也就是Fu类的函数(是先于对象建立之前就存在了,无法被后出现的Zi类对象所复写的,所以没发生复写.

原文链接:https://blog.csdn.net/ChaoticNg/article/details/93176680

强制转换

父类的引用 指向 子类对象。

把子类转化为父类,向上转型;

把父类转化为子类,向下转型;强制转换。强制转换可能丢失方法。

强制转换(Student)s2).eat()。

static

匿名代码块:对象创建就会执行(可以用来赋初始值)

静态代码块:只执行一次。

image-20241121211455967

抽象类

抽象类的所有方法必须由其子类实现,除非其继承子类仍然为抽象类。

抽象类中可以包含普通方法,但一旦有抽象方法就是抽象类。

//abstract抽象类 :类 extends:单继承 (接口可以多继承)

public abstract class Action{
    //抽象方法,只有方法名字,没有方法实现
 public abstract void doSomething();
}

特点:不能new抽象类,只能靠子类去实现他 : 约束

抽象类包含构造器,子类继承父类后仍然需要父类构造器

接口

普通类:只有具体实现

抽象类:具体实现和规范(抽象方法)都有!

接口:只有规范。 约束和实现分离

接口就是规范,定义的是一组规则。接口的本质是契约。

//接口都需要有实现类
public interface UserService{
    
    //常量
    public static final int AGE=99;
    int AGE=99;//相同(不常用常量)
    
	//接口中所有定义都是抽象的 public abstract
	void add(String name);
	void delete(String name);
}
public interface TimeService{
	void timer();
}
//实现接口的类 就需要重写接口中的方法
public class UserServiceImpl implements UserService,TimeService{
    @override
    public void add(String name){
    
    }
    
    @override
    public void delete(String name){
    
    }
    
    @override
    public void timer(){
    
    }
}

作用:

  1. 约束
  2. 定义一些方法,让不同人实现
  3. 接口中所有定义都是抽象的 public abstract
  4. 接口中所有常量都是public static final
  5. 不可以被直接实例化,没有构造方法(抽象类有构造方法)

内部类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类
public class Outer{
    private int id;
    public void out(){
        System.out.println("外部类");
    }
    
    public class Inner{
        public void in(){
            System.out.println("内部类");
        }
       
       //内部类可以直接获得外部类的私有属性和方法,不用创建外部类对象
       public void getID(){
          System.out.println(id);  
       }
    }
}
Outer outer=new Outer();
//通过外部类来实例化内部类
Outer.Inner inner=outer.new Inner();
inner.in();

内部类可以直接获得外部类的私有属性和方法,不用创建外部类对象

局部内部类:

public class Outer{
	public void method(){
        class Inner{		//局部内部类
            
        }
        
    }
}
//一个java类中可以有多个class类,而只能有一个public class类
class A{
public static void main(String[] args){
}
}

匿名内部类

public class Test{
public static void main(String[] args){
    //没有名字初始化类,不用将实例保存到变量中
	new Apple().eat();
	}
}
class Apple{
    public void eat(){
        
    }
}

标签:07,构造方法,子类,void,面向对象,父类,方法,public
From: https://www.cnblogs.com/cookiesDing/p/18576047

相关文章

  • 在Python中什么是面向对象思维?
    目录1.引言2.面向对象编程(OOP)的基础概念2.1面向对象编程的定义2.2面向对象与面向过程的区别3.Python中的面向对象编程核心要素3.1类与对象3.2属性与方法3.3封装、继承与多态4.Python实现面向对象的基础操作4.1定义类与实例化对象 4.2类的属性与方法4.......
  • 面向对象编程(基础部分)
    java设计者,引入OOP,根本原因是,现有技术不能完美解决新的需求0eg:张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示张老太没有这只猫猫。1.......
  • 面试题 02.07. 链表相交
    题目自己写的:/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode(intx):val(x),next(NULL){}*};*/classSolution{public:ListNode*getIntersection(ListNode*headA,ListNode*hea......
  • 20222407 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容1.1本周内容总结使用了Metasploit框架,其是一个功能强大的渗透测试框架。在使用的过程当中,Metasploit提供了种类繁多的攻击模块,涵盖了远程代码执行、服务拒绝、提权等多种攻击方式,支持对多种操作系统和应用程序进行测试。除了漏洞利用,它还具备强大的后渗透功能,如键......
  • [luoguSP10707] Count on a tree II
    题意原题链接给定一棵树,节点\(i\)上有颜色\(c_i\),多次询问,每次查询两点之间的路径中的不同颜色数。sol这是一道类似普通莫队[luoguSP3267]D-query的题目,但是是在树上询问的,因此考虑将树转化为序列计算。将树转化为序列包括DFS序,欧拉序和树链剖分三种,树链剖分复杂度更......
  • 软件设计:实验1:UML与面向对象程序设计原则
    实验1:UML与面向对象程序设计原则本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、掌握面向对象程序设计中类与类之间的关系以及对应的UML类图;2、理解面向对象程序设计原则。 [实验任务一]:UML复习阅读教材第一章复习UML,回答下述问题:面向对象程序设计中类与类的关......
  • 重拾JS-面向对象/原型以及原型链
    简言最近在做前端知识的复习和整理,有了一些自己新的体会。更多在于记录,通过反复的温习,写笔记消除自己以前学习知识点的误区什么是面向对象?要理解什么是面向对象,那么首先要知道什么是面向过程面向过程比如以做饭为例graphTD买菜-->切菜-->炒菜-->装盘在上述流程图中......
  • springboot汽车售票系统-毕业设计源码07891
    基于springboot的汽车售票系统摘 要汽车售票系统主要功能模块包括系统用户管理、车次车票信息、车票预定、退票信息、改签信息等,采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取MySQL作为后台数......
  • java面向对象知识点: 封装,构造,重载
    目录封装封装知识点private(私有)public(公共) 二、getter和setter方法getter方法(访问器方法)setter方法(修改器方法)三、封装类的设计原则单一职责原则高内聚性一.Java为什么要封装?一、数据隐藏与安全性保护数据不被随意访问防止外部干扰二、提高代码的可维......
  • 【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)
    【RAG项目实战07】替换ConversationalRetrievalChain(单轮问答)NLPGithub项目:NLP项目实践:fasterai/nlp-project-practice介绍:该仓库围绕着NLP任务模型的设计、训练、优化、部署和应用,分享大模型算法工程师的日常工作和实战经验AI藏经阁:https://gitee.com/fasterai......