zoukankan      html  css  js  c++  java
  • Django3.2学习笔记

    基本常用命令

    django-admin

    django-admin startproject myproject:创建一个django工程,其中myproject为工程名;
    执行上述命令后,会生成如下目录结构:
    myproject/
    |------myproject/
    |        |------__init__.py
    |        |------asgi.py
    |        |------settings.py:Django项目配置文件,包括Django模块应用配置、数据库配置、模板配置等
    |        |------urls.py:Django路由配置
    |        |------wsgi.py:与WSGI兼容的Web服务器,为项目提供服务入口
    |------manage.py:命令行工具,支持不同的交互运行方式

    manage

      说明:manage.py在Django工程目录下,执行python manage.py命令时,需要先进入工程目录下
    • python manage.py startapp myapp:创建一个App,其中myapp为App名称;
    执行上述命令后,会在myproject工程目录下生成如下目录结构:
    myproject/
    |------myproject/:目录结构参见django-admin命令执行后生成的目录结构
    |------manage.py:命令行工具,支持不同的交互运行方式
    |------myapp/
    |       |------migrations/:用于记录models中数据结构的变更
    |       |------__init__.py
    |       |------admin.py:Django自带的后台管理
    |       |------apps.py:用于应用程序配置
    |       |------models.py:Django数据模型,定义应用程序数据结构(对应数据库的相关操作)
    |       |------tests.py:Django测试用例相关
    |       |------views.py:Django视图模块,控制前面页面显示的内容
    • python manage.py runserver 127.0.0.1:8000:启动Django项目,其中127.0.0.1:8000为项目访问地址及端口
    • python manage.py shell:以终端命令交互的方式启动Django项目
    • python manage.py test:执行Django测试用例,默认为myproject/myapp/tests.py中的用例
    • python manage.py makemigrations:创建数据模型变更记录,当数据模型发生变化时,会在myproject/migrations目录下生成新的形如"0001_initial.py"的文件
    • python manage.py migrate:数据库迁移,当settings中配置好数据库后,执行此命令会在数据库中生成相应的数据表结构

    Django架构

    MVC & MTV

        0
    Model数据模型
    数据存取层,定义系统的数据表结构
    View视图模块
    建立用户与系统的连接页面,用户通过request发送请求给Controller,再由Controller分发到指定的路由,经过Model层的数据存取,最终将数据渲染到指定模板文件,并最终呈现到页面中,由视图和模板组成
    Controller控制模块
    将用户提交的request分发给View模块的视图函数

    MTV

        0
    Model数据模型
    数据存取层,定义系统的数据表结构、数据的存取,通过View模块联接
    View视图模块
    业务逻辑层,包括数据模型的存取及调用适当的模板文件的相关逻辑,类型于模型与模板之间的桥梁
    Template模板文件
    表现层,渲染View层的数据并最终呈现在页面中

    运行流程

    说明:由于Django的URLConf自动完成,因此C层被弱化,而T层被单独抽出
    如上图:
    1.用户通过web浏览器向apache服务器发起请求;
    2.apache服务器将请求转发给urls模块;
    3.urls.py至上而下匹配路由配置,匹配成功后,将请求交给视图模块views对应的视图函数处理;
    4.视图函数接收到请求后,将相应的数据请求交给models数据模型;
    5.models通过ORM操作数据库;
    6.数据库操作完成后,将结果返回给models;
    7.models将数据结果返回给views视图函数;
    8.views视图函数将数据结果,并通过指定的模板文件进行渲染;
    9.将渲染后的模板文件最终呈现给web浏览器

    URLconf

      Django通过URLconf模块来维护网址的解析与views视图函数的对应关系。

    常用方法:(django.urls模块)

    方法
    说明
    示例
    path
    指定的地址为确定的地址,不支持正则匹配
    path("", views.index)
    re_path
    指定的地址为不确定的地址,支持正则匹配
    re_path("user/(?Pd+)", views.user)
    include
     
    path("api/", include("allauth.urls"))
    reverse
    反向生成URL地址,其参数为urls.py中视图函数对应的name参数
    reverse('add')
    说明:当re_path中使用的正则表达式如(?P<tid>d+)时,视图函数的参数名必须指定为tid

    参数说明

    • name:类似于网址的别名,可用于templates、models、views中得到对应的网址,只要这个名字不变,即使网址发生了变化,也能通过这个名字找到正确的网址;

    在模板文件中的应用

    View Code
    View Code
    如果网址发生变化但网址别名未发生变化时,通过别名可正确识别变化后的网址,如将新的路由配置修改为如下
    View Code
    View Code

    在视图函数中的应用

    View Code
    • include:路由转发,用于从根路由出发,将app所属url请求转发到子urls.py中,path/re_path中使用;

    方法一:只指定urls模块的字符串

    View Code

    方法二:同时指定urls(模块字符串、app_name)、命名空间(当存在多个app时,指定namespace很有必要)

    View Code

    api/urls.py

    View Code

    mblog/urls.py

    View Code

    在template中使用命名空间

    View Code

    在views中使用命令空间

    View Code
    注意:namespace与name在模板文件和视图函数中使用的时候要用冒号分隔,如:"api:host"

    Template

    配置

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',    # 默认模板引擎
            'DIRS': [],  # 默认为app目录下的templates目录
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    View Code
    • BACKEND:模板引擎,可使用指定的模板引擎,如django.template.backends.jinja2.Jinga2
    • DIRS:模板文件目录,默认为app目录下的templates目录,可指定特定的目录,常用方式[os.path.join(BASE_DIR, "templates")]

    View中的使用

    到底使用哪个模板进行渲染,由views.py的视图函数决定

    from django.shortcuts import render
    
    # Create your views here.
    def index(request):
        return render(request, "index.html")
    View Code
        0
    render(request, "index.html", {"username": username})
    第一个参数为request,第二个参数为模板文件,第三个为可选参数,接收一个dict类型,在index.html模板文件中需要使用的变量,可通过这个dict参数传入
    说明:第三个参数可利用python的locals()函数替换

    使用现有模板框架(此处以bootstrap3为例)

    目前接触到使用bootstrap3的方法有两种,分别是静态引用和动态加载

    • 静态引用

    1.安装bootstrap3

    pip install django-bootstrap3

    2.在settings.py的INSTALLED_APPS中添加bootstrap3应用

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'myapp',
        'bootstrap3',
    ]
    View Code

    3.在模板文件中引用bootstrap3

    <head>
        <meta charset="UTF-8">
        {% load bootstrap3 %}
        {% bootstrap_css %}
        {% bootstrap_javascript %}
        <title>MySite</title>
    </head>
    View Code
    • 动态加载

          直接通过bootstrap官网,找到CDN并复制到<head></head>标签中

    # 在https://getbootstrap.com/docs/3.4/getting-started/#download网址中,找到BootstrapCDN,
    # 将其复制到模板文件的<head></head>标签中即可
    # jQuery框架同样可以采用此种方式加载
    
    <head>
        <meta charset="UTF-8">
        <title>MySite</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
              integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu"
              crossorigin="anonymous">
    
        <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
              integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ"
              crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.6.0.js"
                integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous">
        </script>
        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
                integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"
                crossorigin="anonymous">
        </script>
    </head>
    View Code

    支持的语法

    {%%}{{}}

    {% if exp %}
    条件控制语法,语法同python,使用{% endif %}结束条件控制,可配合{% else %}、{% elif %}使用形成分支结构
    {% if username %}

    登出

    {% else %}

    登录

    {% endif %}
    {% for %}
    循环控制语法,语法同python,使用{% endfor %}结束循环控制
     
    {% for user in usersusers %}

    {{ user.name }}

    {% endfor %}
     
    可配合{% empty %}显示特定内容,内部变量:forloop
    注意:内部变量forloop只在{% for %}循环内生效,当检测到{% endfor %}时,forloop即失效不可用
     
    {% for user in usersusers %}

    {{ user.name }}

    {% empty %}

    There are no athletes. Only computer programmers.

    {% endfor %}
     
    forloop.counter:表示循环次数,从1开始开始计数
    {% for user in users %}

    {{ forloop.counter }}: {{ user }}

    {% endfor %}
    forloop.counter0:也表示循环次数,但是从0开始计数
    {% for user in users %}

    {{ forloop.counter0 }}: {{ user }}

    {% endfor %}
    forloop.revcounter:循环中剩余元素数量,初始值为元素总数,最后一次为1
     
    forloop.revcounter0:也是循环剩余元素数量,不过初始值为元素总数-1,最后一次为0
     
    forloop.first:Bool类型,第一次循环时返回True,否则返回False
    {% for object in objects %}
    {% if forloop.first %}
     
    {% else %}
     
    {% endif %}
    {{ object }}
     
    {% endfor %}
    forloop.last:Bool类型,最后一次循环时返回True,否则返回False
     
    {% extends %}
    html继承语法,base.html为html模板文件,类比于Python的基类
    {% extends "base.html" %}
    {% include %}
    html引用语法,将其他html模板文件导入到该html文件中,一般用于网页的页眉、页脚
    {% include "header.html" %}
    {% include "footer.html" %}
    {% load %}
    html加载静态文件/框架
    {% load bootstrap3 %}
    {% load static %}
    {% block %}
    用于继承及实现;在base.html模板文件中定义了{% block %}{% endblock %}之后,所有继承base.html文件的模板文件都必须实现{% block %}{% endblock %}修饰的内容
    base.html
    {% block title %}{% endblock %}
    index.html
    {% extends "base.html" %}
    {% block title %}MySite{% endblock %}

    使用静态文件

    Django中,使用静态文件的方式,可以一度程序上提高性能。而Django的静态文件默认存储在templates/static中

    settings.py中的默认配置

    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/3.2/howto/static-files/
    
    STATIC_URL = '/static/'
    View Code
    当然,我们同样可以通过在settings.py中配置的方式来指定静态文件的存放位置
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/3.2/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static"),
    ]
    View Code
    当配置为上述路径后,静态文件的目录路径则变更为与app同级目录的static目录,对于images、css、js则分别创建相应的目录即可
    而在template模板文件中使用静态文件时,则按照如下方式即可正常引用静态文件了
    <hr>
    {% load static %}    # 加载静态文件
    <img src="{% static 'images/logo.png' %}" width=100>
    <em>Copyright 2016 a
        <a href="http://www.baidu.com">http://www.baidu.com</a>.
        All rights reserved.
    </em>
    View Code

    常用过滤器

    过滤器名称
    用法
    示例
    capfirst
    将字符串首字母大写
    {{ msg | capfirst }},如果msg内容为"django",则html中显示将变成"Django"
    center/ljust/rjust
    为字符串加上指定空格后居中、靠左、靠右对齐
    {{ msg | center: "15" }}
    cut
    在字符串中删除指定的子字符串
    {{ msg | cut: " " }},如果msg内容为" How are you",则html中显示将变成"Howareyou"
    date
    设置日期的显示格式
    {{ value | date:"D d M Y" }},value为datetime的标准格式。可利用date来设置显示格式
    default
    如果没有值,就使用默认值
    {{ msg | default:"没有信息" }}
    first/last
    只取出列表数据中的第一个/最后一个元素
    {{ values | first }} {{ values | last }},values为列表元素
    floatformat
    以指定的浮点数格式显示数据
    {{ value | floatformat:3 }},如果value为123.45678,则html中显示将变成123.457
    linebreaks
    将文字内容中的换行符号转换成HTML的
    {{ msg | linebreaks }}
    linebreadsbr
    将文字内容中的换行符号转换成HTML的
    {{ msg | linebreaksbr }}
    linenumber
    为显示的文字内容加上行号
    {{ msg | linenumber}}
    lower/upper
    将显示的文字内容转换成小写/大写
    {{ msg | lower }} {{ msg | upper }}
    random
    以随机数将数据内容显示出来
    {{ values | random }}
    safe
    标记字符串为安全的,不需要再处理转义字符
    {{ msg | safe }}
    striptags
    去掉文字内容中的所有HTML标签
    {{ msg | striptags }}
    truncatechars
    把过长的字符串裁切成指定的长度,并将最后3个字符转换成...
    {{ msg | truncatchars:12 }}
    yesno
    按照值的内容True/False/None,显示出有意义的内容
    {{ value | yesno:"是,否,可能吧" }}

    Models

      Django中,models负责定义数据模型,通过views中的视图函数与Django Models机制的交互,调用相应的驱动程序接口,实现对数据的存取

    配置

    在默认配置中,Django以SQLite作为数据库管理系统,当然也可以使用其他的数据库管理系统
    # Database
    # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': BASE_DIR / 'db.sqlite3',
        }
    }
    View Code
    配置链接 mySQL 数据库
    # mysql
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # 数据库驱动
            'NAME': 'event',  # 数据库名称(需要先创建)
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '123456',  # 数据库密码
            'HOST': '',  # 数据库主机,留空默认为localhost
            'PORT': '3306',  # 数据库端口
        }
    }
    View Code
    配置链接PostgreSQL 数据库
    # postgresql
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql_psycopg2",
            "NAME": "event",
            "USER": "postgres",
            "PASSWORD": "123456",
            "HOST": "localhost",
            "PORT": "5432",
        }
    }
    View Code

    定义模型类

    Django提供了完善的模型(model)层来创建和存取数据,它包含你所存储的数据的必要字段和行为以及类型;
    • 每一个模型都是一个python类,并且继承自django.db.models.Model类
    • 该模型的每个属性都表示一个数据库表的字段
    • 每个模型自动生成一个auto_increment的id字段,并作为主键
    • 内部类Meta:用于指定一些特殊属性,如ordering(排序规则)、unique_together(联合外键)  
    示例:
    from django.db import models
    
    class Poll(models.Model):
    
        name = models.CharField(max_length=200, null=False)
        create_at = models.DateField(auto_now_add=True)
        enabled = models.BooleanField(default=False)
        
        class Meta:
            ordering = ("-create_at",)     # 定义结果的排序规则,此处按照创建时间进行排序,"-"表示按照倒序排序
    
        def __str__(self):
            return self.name
    
    class PollItem(models.Model):
    
        poll = models.ForeignKey(Poll, on_delete=models.CASCADE)  # 指定PollItem表的外键为Poll
        name = models.CharField(max_length=200, null=False)
        image_url = models.CharField(max_length=200, null=True, blank=True)
        vote = models.PositiveIntegerField(default=0)
    
        def __str__(self):
            return self.name
     
    View Code

    使用admin后台管理数据模型

    Django提供了admin后台管理,对于自定义的数据模型,只需要将数据模型注册到admin后台管理中就可以了
    而注册admin后台管理也非常简单,在admin.py中引入数据模型,并调用admin.site.register()方法就可以了
    from django.contrib import admin
    from mysite.models import Poll
    
    
    admin.site.register(Poll)
    View Code
    为了在admin后台管理中能显示更多的字段,可利用django.contrib.admin.ModelAdmin派生出新的类,并在新的类中对想要的属性进行调整
    from django.contrib import admin
    from mysite.models import Poll, PollItem
    
    
    class PollAdmin(admin.ModelAdmin):
    
        list_display = ("name", "create_at", "enabled")
        ordering = ("-create_at",)
    
    
    class PollItemAdmin(admin.ModelAdmin):
    
        list_display = ("poll", "name", "vote", "image_url")
        ordering = ("poll", )
    
    
    admin.site.register(Poll, PollAdmin)
    admin.site.register(PollItem, PollItemAdmin)
    View Code
    django.contrib.admin.ModelAdmin中提供了很多定制化的属性
    • list_display:可迭代对象,其中每个对象对应数据模型中定义的属性,如:list_display = ("name", "create_at", "enabled")
    • search_fields:搜索器,可迭代对象,同上,如:search_fields = ("name", "poll")
    • ordering:同上,如:ordering = ("-create_at")
    • list_filter:过滤器,可迭代对象,如:list_filter = ("enabled")

    常用Model属性类型

    admin.Model提供的常用属性

    AutoField
    一个IntegerField类型的自增字段类型
    BooleanField
    用于存入布尔类型的数据(True/False)
    CharField
    用于存放字符型的数据,需要指定数据长度,max_length
    DateField
    日期类型,必须是"YYYY-MM-DD"格式
    DateTimeField
    日期时间类型,必须是"YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]"
    DecimalField
    定点数类型,max_digits指定最大值,decimal_places指定小数位数
    EmailField
    电子邮件类型
    FilePathField
    文件路径类型
    FloatField
    浮点数类型
    IntegerField
    integer类型,数值范围从-2147483648g到2147483647
    BigIntegerField
    用于存放大的integer类型
    GenericIPAddressField
    存放IP地址类型,支持IPv4和IPv6的字符串格式
    NullBooleanField
    类似BooleanField类型,但允许为NULL
    PositiveIntegerField
    integer类型,范围0~2147483647
    TextField
    用于存放文本类型的数据
    TimeField
    时间类型,必须是"HH:MM[:ss[.uuuuuu]]"格式
    URLField
    用于存放URL地址
    BinaryField
    存储原始二进制数据的字段
    注意:在models数据模型定义中,属性中加上verbose_name可定义属性的中文名

    在models.ForeignKey(Poll, on_delete=models.CASCADE)中on_delete参数,支持五种操作:

    • on_delete=models.CASCADE:删除被引用的对象时,此对象也一并被删除
    # models.py
    from django.db import models
    
    class AClass(models.Model):
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    class AListClass(models.Model):
        a_name = models.ForeignKey(AClass, on_delete=models.CASCADE)
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
            
    # admin.py
    from django.contrib import admin
    from mysite.models import AClass, AListClass
    
    class AListClassAdmin(admin.ModelAdmin):
        list_display = ("name", "a_name")    # AListClass表显示name字段及外键AClass的name字段
    
    admin.site.register(AClass)
    admin.site.register(AListClass, AListClassAdmin)
    View Code
    AClass表添加A1、A2实例,同时AListClass添加a1、a11两个实例关联A1,a2、a22两个实例关联实例A2
    0
    当删除AClass表的A1实例时,会将AListClass表中相关联的a1、a11实例都删除
    0
    确认删除后,查看AListClass表中,已不存在a1、a11的数据
    0
    • on_delete=models.PROTECT:禁止删除并抛出异常ProtectdError
    # models.py
    from django.db import models
    
    class BClass(models.Model):
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    class BListClass(models.Model):
        b_name = models.ForeignKey(BClass, on_delete=models.PROTECT)
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    # admin.py
    from django.contrib import admin
    from mysite.models import BClass, BListClass
    
    class BListClassAdmin(admin.ModelAdmin):
        list_display = ("name", "b_name")
    
    admin.site.register(BClass)
    admin.site.register(BListClass, BListClassAdmin)
    View Code
    BClass表添加B1、B2实例,同时BListClass添加b1、b11两个实例关联B1,b2、b22两个实例关联实例B2
    0
    当删除BClass表的B1实例时,会提示"Cannot delete b class",并提示需要先删除依赖实例B1的实例才能删除B1实例
    0
    删除BListClass表的b1、b11这两个依赖B1的实例
    0
    再次尝试去删除BClass表的B1实例,这次就能正常删除B1实例了
    0
    • on_delete=models.SET_NULL:当被引用的对象被删除后,依赖它的其他对象的该字段都被设置为NULL;设置此操作时,字段必须设置null=True来允许字段值为NULL
    # models.py
    from django.db import models
    
    class CClass(models.Model):
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    class CListClass(models.Model):
        c_name = models.ForeignKey(CClass, on_delete=models.SET_NULL, null=True)  # 必须指定null=True允许字段值为空
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    # admin.py
    from django.contrib import admin
    from mysite.models import CClass, CListClass
    
    class CListClassAdmin(admin.ModelAdmin):
        list_display = ("name", "c_name")
    
    admin.site.register(CClass)
    admin.site.register(CListClass, CListClassAdmin)
    View Code
    CClass表创建C1、C2实例,CListClass表添加c1、c11两个实例关联实例C1,c2、c22两个实例关联实例C2
    0
    当删除CClass的C1实例时,与它相关联的CListClass表的c1、c11实例的c_name字段会被设置为NULL
    0
    • on_delete=models.SET_DEFAULT:当被引用的对象被删除后,依赖它的其他对象的该字段都被设置为默认值;设置此操作时,字段必须设置default参数
    # models.py
    from django.db import models
    
    class DClass(models.Model):
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
    
    class DListClass(models.Model):
        d_name = models.ForeignKey(DClass, on_delete=models.SET_DEFAULT, default=None, null=True)
        name = models.CharField(max_length=40)
    
        def __str__(self):
            return self.name
            
    # admin.py
    from django.contrib import admin
    from mysite.models import DClass, DListClass
    
    class DListClassAdmin(admin.ModelAdmin):
        list_display = ("name", "d_name")
    
    admin.site.register(DClass)
    admin.site.register(DListClass, DListClassAdmin)
    View Code
    DClass表创建D1、D2实例,DListClass表创建d1、d11两个实例关联D1实例,创建d2、d22两个实例关联D2实例
    0
    当删除DClass的D1实例时,与它相关联的DListClass表的d1、d11实例的d_name字段会被设置为默认值,此处为NULL
    0
     
    • on_delete=models.DO_NOTHING:什么事儿都不做?如果你的数据库后端强制引用完整性,它将引发一个IntegrityError ,除非你手动添加一个ON DELETE 约束给数据库
    出来混,迟早是要还的...
  • 相关阅读:
    Spring Boot面试题(转至)
    深入理解Java输入输出流
    java基础 第十六章(连接数据库)
    java基础 第十五章(数据库)
    java基础 第十四章(Servlet声明周期、Servlet向jsp中提供数据、Servlet跳转jsp、jsp中书写java代码)
    java基础 第十三章(HashMap、Servlet介绍)
    java基础 第十二章(异常处理、工具类、集合)
    java基础 第十一章(多态、抽象类、接口、包装类、String)
    java基础 第十章(this,继承,重写和重载的区别)
    java基础 第九章(设计模式 单例模式)
  • 原文地址:https://www.cnblogs.com/blackeyes1023/p/15009979.html
Copyright © 2011-2022 走看看