java面向对象OOP

基本概念

  1. 面向过程与面向对象

    面向过程:关注代码实现的细节、复用性

    面向对象:先把每个过程的代码实现细节整合到对象中,只要找到对象就能拥有对象身上所有的功能。

    面向对象基于面向过程

  2. 类与对象

    对一类对象进行抽取,对共有的特征抽取成属性,共有的行为抽取成方法,这一类对象抽取成类。 — 类就是对象的概括,对象是类的具体实现

    在java中所有非静态的属性和方法都要通过对象调用

    万物皆对象

  3. 构造方法

    • 与类同名,没有返回值类型

    • 如果类中没有定义任何形式的构造方法,JVM会在底层默认添加一个无参构造

    • 构造方法支持重载,有参构造可以进行属性初始化

    • 如果类中定义任何形式的构造方法,JVM不会再添加无参构造

    • 类中最少会有一个构造方法

  4. this指针

    • 关键字:代表当前类的对象

    • this可以代表类还没有产生对象,可以代表类刚创建的对象,也可以代表正在使用的对象

    • this不是真实的对象,是一个虚拟的指代,指代地址值

    • this的主要功能是在本类的构造方法中调用其他形式的构造方法,this语句一定要在构造方法的首行

    示例:

    class Person {// 特征 --- 属性String name;char gender;int age;// 如果一个类中没有定义构造方法,JVM在底层会默认定义一个无参构造// 构造方法特点: 1.与类同名 2. 没有返回值类型public Person(){System.out.println("this:" + this);  // this:cn.zss.Person@15aeb7ab}// 支持重载,有参构造// 如果类中定义了任意一个构造方法,JVM不会再添加public Person(String name){// this (关键字)// 代表当前类的对象this.name = name;System.out.println("A");System.out.println("this:" + this);}public Person(String name, int age, char gender){// this 语句在本类中的构造方法中调用其他形式的构造方法// this 语句一定要在首行this(name);this.gender = gender;this.age = age;System.out.println("B");}// 行为 --- 方法public void eat(){// this可以代表类还没有产生对象System.out.println(this.name + " eat too much");System.out.println("this:" + this);  // this:cn.zss.Person@15aeb7ab}
    }public class Demo{public static void add (int num){num += 1;}// 只要参数是引用类型只能接受对象public static void add (Person p){// new Person() 形参接受Person类对象p.age ++;}public static void main(String[] args) {// 构造方法,创建对象Person p = new Person();p.age = 19;p.name = "lili";p.eat();  // lili eat too much// 实参传入基本数据类型System.out.println(p.age);  // 19add(p.age);System.out.println(p.age);  // 19// 实参传入引用数据类型add(p);System.out.println(p.age);  // 20System.out.println("--------------------------------------");Person p2 = new Person("Poter",18,'男');}
    }
    
  5. 构造代码块

    • 在类内方法外的{}内
    • 用于属性初始化
    • 优先于任意形式的构造方法执行

    示例:

    class Baby {// 属性String name;char gender;int age;// 构造代码块// 会优先于所有的构造方法先执行,与位置无关{this.name = "Poter";this.gender = '男';}// 无参构造public Baby(){System.out.println("无参构造方法");}public Baby(String name, int age){this.name = name;this.age = age;System.out.println("有参构造方法");}
    }public class Demo{public static void main(String[] args) {Baby a = new Baby();System.out.println(a.name+","+a.gender);Baby b = new Baby("xiaoming",1);System.out.println(b.name+","+b.gender+","+b.age);}
    }
    
  6. 局部代码块

    • 在方法内的{}
    • 控制变量的生命周期,提高内存的利用率

    示例:

    public class Demo{public static void main(String[]args){int x = 1;//局部(方法)代码块//改变变量的生命周期{int y = 2;System.out.println(x+y);}     }
    }
    
  7. 局部变量与成员变量

    a. 位置

    • 成员变量:类内方法外

    • 局部变量:方法内

    b. 使用范围

    • 成员变量:整个类

    • 局部变量:方法内

    c. 内存

    • 成员变量:堆
    • 局部变量:栈

    d. 生命周期

    • 成员变量:随着类创建的对象而产生,随着对象被系统回收时才消失
    • 局部变量:方法被调用执行时才产生,随着方法的调用结束才消失

面向对象的特性

  • 封装、继承、多态(抽象)

封装

  1. 类,方法 — 体现了封装的复用性
  2. 属性私有化 — 类中的属性进行私有化,提供公共的访问方式(方法)用于间接的操作私有化属性,提高代码的数据安全性

示例:

public class ObjectDemo {public static void main(String[] args) {Person p = new Person("lili",18,'女');p.setAge(20);System.out.println(p.getAge());}
}
class Person{// 私有化属性只能在本类中直接使用private String name;private char gender;private int age;public Person(String name, int age, char gender){// 对参数进行判断this.name = name;this.gender = gender;if (age >=0 && age <= 120){this.age = age;}}// 自己定义的getter 和 setter 方法// 提供方法间接给属性赋值public void setAge(int age){if (age >=0 && age <= 120){this.age = age;}else{System.out.println();}}// 提供方法间接的获取属性值public int getAge(){return this.age;}// java 可以提供自动提供的get方法和set方法// 右键 点击 Generator --- 选择Getter and Setter}

继承

  • 如果多个类的内容出现重复,就要把重复的内容放到新类中,原来的类和新类之间通过extends关键字产生关联关系—继承。原来的类叫子类(派生类),新的类叫父类(超类)。子类可以继承父类的部分信息

  • 继承可以提高代码的复用性

  • 继承的方式(单继承 树状结构):类只能有一个父类,但可以有多个子类

  • 方法的重写:在父子类中出现方法签名一致的方法

    • 重写原则:两等两小一大

      • 两等:方法签名一致;如果父类的方法返回值类型是基本数据类型或者void, final,那么子类的返回值类型就和父类完全一致

      • 两小:如果父类的方法返回值类型是引用类型,那么子类的方法返回值类型要么和父类的方法返回值类型一致,要么是父类方法返回值类型的子类;子类抛出异常小于等于父类异常类型

        class A{}
        class B extends A{}
        class C{public A m(){  // 返回值类型为Areturn null;}
        }
        class D extends C{public B m(){  // 返回值类型为A的子类return null;}
        }
        
      • 访问权限修饰符

        关系:本类,子类,同包类,其他类

        本类 子类 同包类 其他类
        public 可以 可以 可以 可以
        protected 可以 可以 可以 不可以
        默认 可以 同包子类 可以 不可以
        private 可以 不可以 不可以 不可以

        **一大:**子类的方法访问权限修饰符要么和父类的方法访问权限修饰符一致,要么比父类的范围大

        class EDemo{// 类的私有化,对子类不可见private void m(){ }void n(){}  // 默认
        }class EDemo1 extends EDemo{public void m(){ } // 不是重写,相当于定义一个新方法public void n(){}  // 重写,public范围大于默认范围
        }
        

        **父类私有化信息、构造方法、构造代码块都不能被子类继承 **

        public class ExtendDemo2 {}class EDemo{// 类的私有化,对子类不可见private void m(){ }void n(){}  // 默认
        }class EDemo1 extends EDemo{public void m(){ } // 不是重写,相当于定义一个新方法public void n(){}  // 重写
        }
        

        注意: 如果protected修饰的信息和要获取的位置关系是其他类位置,保证子类对象只能在本类中使用才能调用protected修饰的信息

        /*定义packet cn.zss.a中的类A*/
        package cn.zss.a;
        public class A {protected void m(){}
        }/*定义packet cn.zss.b中的类B和C*/
        package cn.ysu.b;import cn.ysu.a.A;  // 导入类A的包public class B extends A{public static void main(String[] args) {// 创建对象A a = new A();B b = new B();// a对象和m()所在的位置是其他类// a.m();  // error 无法访问protected修饰的方法b.m();  // correct// b对象和m()所在位置是其他类,B类继承A类}
        }class C extends A{public void n(){C c = new C();c.m();// c对象和m()所在位置是其他类,C类继承A类B b = new B();// b.m();  // error// 如果protected修饰的信息和要获取的位置关系是其他类位置// 保证子类对象只能在本类中使用才能调用protected修饰的信息}
        }
        
  • super

    • 关键字,代表父类的对象,可以调用父类的属性和方法

    • super语句—在子类构造方法中调用父类的构造方法

      • 子类**所有形式*的构造方法默认都会通过super()调用父类的无参构造
      • 如果父类没有提供无参构造,子类所有的构造方法需要通过super语句强制调用父类对应形式有参构造
      • super 语句需要在首行 —和this冲突不能同时存在,但是this可以和super()的默认形式(不手动调用)同时存在
    • 父类对象优先于子类对象先存在

      • 父子类执行顺序(父类构造代码块-父类构造方法-子类构造代码块-子类构造方法
    public class ExtendsDemo2 {public static void main(String[] args) {Pig p = new Pig("lili");p.eat();}
    }class Animal{// 父类对象优先于子类对象先存在
    //    public Animal(){//        System.out.println("父类的无参构造");  // 1
    //    }
    //public Animal(String name){System.out.println("父类的有参构造");}// 方法public void eat(){System.out.println("Animals are eating");}public void sleep(){System.out.println("zzz...");}
    }class Pig extends Animal{// 父类对象优先于子类对象先存在// 若父类没有无参构造需要手动调用父类的有参构造// super 语句需要在首行public Pig() {super("lili");  // 手动调用父类有参构造,否则报错// supper语句 --- 在子类的构造方法中调用父类的构造方法// super(); 默认System.out.println("子类的无参构造");  // 2}// 子类所有形式的构造方法都会默认先调用父类的无参构造public Pig(String name){super("lili");  // 手动调用父类有参构造,否则报错System.out.println("子类有参构造函数");}// 重写方法public void eat() {System.out.println("The pig is eating");// 在java中所有非静态属性和方法都需要对象调用// this -代表当前类的对象// supper - 代表父类的对象sleep();  // 相当于 super.sleep();}
    }
    

多态

  • 在代码执行过程中可以呈现的多种形式
  1. 编译时多态 — 在编译时期绑定代码

    • 体现:重载
  2. 运行时多态 — 在运行时期绑定代码

    • 体现:重写,向上造型(在执行时才能知道对象调用的方法)

    • 前提:继承

    • 向上造型

      • 声明类是父类,实际创建的类是子类
      • 编译看左边引用的类型,运行看具体的对象类型
      • 向上造型的对象调用方法,可以调用哪些方法看父类,方法的具体执行看子类是否重写父类的方法,如果有重写调用子类方法,否则调用父类方法(父类 — 目录 子类 — 正文)
    • 优点:

      • 统一参数类型
      • 解耦 (降低耦合度 高内聚、低耦合)
    • 示例:

      public class DTDemo {public static void main(String[] args) {// Pet p;// p = new Dog();Pet p = new Dog();// 声明类是父类,实际创建类是子类// 向上造型// 向上造型的对象调用方法// 可以调用哪些方法看父类// 方法的具体执行看子类是否重写父类的方法// 如果有重写调用子类方法,否则调用父类方法p.eat();  // Dogs like to eat bonesp.sleep();  // zzz...// p.bark();  // error,父类中没有,无法调用// 调用方法// 匿名对象 --- 当做参数使用System.out.println("-------------------------");petsEat (new Pet());  // Pets need to eatpetsEat (new Cat());  // 向上造型  Cats like to eat fishpetsEat (new Dog());  // 向上造型  Dogs like to eat bones}public static void petsEat(Pet p){  // 统一参数类型p.eat();}
      }class Pet{// 方法public void eat(){System.out.println("Pets need to eat");}public void sleep(){System.out.println("zzz...");}
      }class Dog extends Pet{@Overridepublic void eat() {// super.eat();System.out.println("Dogs like to eat bones");}public void bark(){System.out.println("Wang Wang barking");}
      }class Cat extends Pet{@Overridepublic void eat() {// super.eat();System.out.println("Cats like to eat fish");}public void CatchMice(){System.out.println("Cats can catch mice");}
      }
      
    • 解析重写原则

      1. 子类的方法访问权限修饰符要么和父类方法访问权限修饰符一致,要么比父类的范围大

        class A{public void fun(){}
        }
        class B extends A{void fun(){}  // 反证,证明这是错的
        }A a = new B();  // 向上造型的对象a的声明类为A类,可以调用A类中的fun(),这个方法在任意位置都能被访问
        a.fun();  // 向上造型调用方法,方法的具体执行看子类(B类),执行B类的fun(),这个方法只能在同包范围内访问
        // 此时前后矛盾,证明“一大”原则正确
        
      2. 如果父类的方法返回值类型是引用类型,那么子类的方法返回值类型要么和父类的方法返回值类型一致,要么是父类方法返回值类型的子类

        class A{}
        class B extends A{}  // B为A的子类
        class C{public B fun(){return null;}
        }
        class D extends C{public A fun(){  // 反证,证明这是错的return null;}
        }C c = new D();  // 向上造型的对象c,声明类C类,可以调用C类中的fun(),返回的是B类型的对象,就能调用B类的方法
        A a = c.fun();  // 向上造型对象调用方法,方法的具体执行看子类(D类),调用D类中的fun(),返回的是A类的对象a,a就可以调用到A类的方法
        // 此时A类中不会包含B类中所有方法,矛盾,证明“一小”的原则是正确的
        

static

  • 关键字,代表静态

  • 可以修饰变量、方法、代码块、内部类

  • static 修饰变量

  • 静态变量 static 变量的定义

  • 静态变量属于类,所以静态变量也称为类变量

  • 生命周期:静态变量随着类的加载(静态常量池)而被加载到方法区的静态区中,在静态区时会对静态变量赋予系统默认初始值,类加载之后不再移除,直到整个程序运行结束,静态变量直到类被移除才会释放

  • 调用静态变量时可以通过类名.静态变量名的形式来调用也可以通过对象.静态变量名调用,为了提高程序可读性,建议通过类名.静态变量名的形式调用。

  • 应用场景:类创建的所有的对象都会对静态变量进行共享 (如果有共享的场景就可以使用静态变量)

  • System.in, System.out,in和out都是静态变量

  • 注意:

    1. 构造代码块当中不能定义静态变量

      • 类加载之后才能创建对象,构造代码块在创建对象时执行,静态变量在类加载时就要初始化
    2. 构造方法不能定义静态变量,原因同上
    3. 构造方法构造代码块中可以给静态变量赋值
    public class StaticDemo {public static void main(String[] args) {Person p = new Person();p.name = "Potter";p.age =18;p.gender = '男';p.eat();System.out.println("name:"+p.name+",gender"+p.gender);Person p1 = new Person();p1.name = "lili";p1.gender = '女';p.eat();System.out.println("name:"+p1.name+",gender:"+p1.gender);System.out.println("name:"+p.name+",gender:"+p1.gender);}
    }class Person{String name;int age;static char gender;public void eat(){System.out.println("People need to eat");}
    }
    

    内存图:

  • static修饰方法

  • static修饰方法

  • 生命周期

    • 静态方法随着类的加载(静态常量池)而加载到方法区的静态区,不会赋予初始值。当调用静态方法时,静态方法会被加载到栈中执行。
  • 调用格式: a.类名.静态方法名()(推荐) b.对象.静态方法名()

  • 注意:

    静态信息只能直接调用静态信息不能直接调用非静态信息,非静态信息可以直接调用非静态信息和静态信息

    1. 静态方法不能定义静态变量

      • 静态方法随着类加载到方法区的静态区中(只是存储方法,并未执行);被调用时才开始运行程序
      • 静态变量在类加载时加载到静态区并初始化
    2. 静态方法不能直接调用非静态方法
      • 非静态变量和非静态方法必须通过对象来调用
      • 当使用类名来调用静态方法时,可能没有创建对象
      • 可以在调用非静态方法之前创建对象,通过对象来调用非静态方法
    3. 静态方法(如 main方法)中不能使用this/super关键字
      this 当前对象 super 父类对象
    4. 子类可以继承父类的静态方法
    5. 静态方法可以重载,但是不能重写
      • 静态方法是和类绑定的
      • 重写针对的是对象 — 与对象一个级别
    6. 子类可以存在与父类方法签名一致的方法,父子类中方法签名一致的方法要么全是静态,要么全是非静态,否则会报错
  1. 静态代码块

    • static修饰构造代码块
    • 在类被使用时执行,包括创建类的对象,调用类的静态方法以及调用类的静态属性
    • 所有的静态信息(静态代码块,静态方法,静态变量)都只加载一次,预先加载一些资源,给静态变量初始化
    • 父子类之间执行顺序(父类静态信息(顺序)-子类静态信息(顺序)-父类对象级别(属性、构造代码块、构造方法)-子类对象级别(属性、构造代码块、构造方法))
    • 注意:
      1. 静态代码块中不可以定义静态变量
      2. 静态代码块可以给静态变量赋值
    class A{static int i = 0;static{  // 静态代码块 --- 不能出现非静态属性 --- 与类同级 --- 预先加载一些资源,静态变量初始化i = 20;System.out.println("静态代码块");}public static void method(){System.out.println("静态方法");}
    }public class StaticDemo2 {public static void main(String[] args) {A a = new A();  // 静态代码块System.out.println(A.i);  // 0System.out.println("------------------------");A.method();  // 静态方法}
    }
    

    示例:

    public class StaticTest3 {public static void main(String[] args) {System.out.println(STDemo1.x + "," + STDemo1.y);// 2, 1}
    }
    class STDemo1{/*加载   执行第一步  执行第二步  执行第三步sd  null     0x01      0x01       0x01x    0        1         2          2y    0        1         1          1*/static STDemo1 sd = new STDemo1(); // 1static int x = 2; // 2static int y;  // 3public STDemo1(){x ++;  // 1y ++;  // 1}
    }
    

final

  • 关键字 — 修饰符
  • 可以修饰数据、方法和类
  1. final 修饰数据

    • final 变量的定义

    • final 修饰的数据就是最终值(无法改变的值)

    • final修饰基本类型数据,基本类型数据的值无法改变

    • final修饰的引用数据类型,引用数据类型的地址值无法改变,元素值依然可以改变

    • 如果final修饰的是成员变量且没有进行初始化,需要保证在创建对象之前要进行初始化

    • 如果final修饰的是静态常量且没有进行初始化,保证在类加载完成之前进行初始化

      class FDemo{final int i1 = 2;// 如果成员变量没有进行初始化,要保证对象创建之前可以给定最终值final int i2;final int i3;// 如果i是静态常量没有进行初始化,要保证在类加载完成之前进行初始化final static int i;// 构造代码块 -- 保证创建对象之前可以给定最终值{i2 = 2;}// 构造方法 -- 保证创建对象之前可以给定最终值public FDemo(){i3 = 7;}static {i = 4;}
      }
      
  2. final修饰方法

    final修饰的方法可以进行重载但不能进行重写

  3. final修饰类

    final修饰的最终类,没有子类(不能被继承),但是可以有父类

abstract

  • 关键字—修饰符 方法、类

  • 如果所有的子类都对父类中某个方法进行了不同程度的重写,那么父类的这个方法的方法体就没有实际意义,把方法体去掉加上abstract修饰就变成了抽象方法

  • 如果一个类中含有抽象方法那么这个类就必须是抽象类。

  • 如果一个普通类继承抽象类那么需要重写所有的抽象方法,如果不想重写所有的抽象方法就要变成抽象类

  • 注意:

    1. 抽象类可以定义属性和方法
    2. 抽象类不一定含有抽象方法
    3. 抽象类可以定义构造方法,不能创建对象
    4. final/static/private不可以修饰抽象方法 — 抽象方法需要被重写所以不能
    5. final不能修饰抽象类— 抽象类需要被继承抽象方法才能被重写
    6. 抽象方法可以支持重载

    示例:

    public class AbstractDemo {public static void getPerimeter(Graph g){System.out.println(g.getPerimeter());}public static void getArea(Graph g){System.out.println(g.getArea());}public static void main(String[] args) {getPerimeter(new Rectangle(2.0, 4.0));getPerimeter(new Circular(2.0));getPerimeter(new Square(2.0));getArea(new Rectangle(2.0, 4.0));getArea(new Circular(2.0));getArea(new Square(2.0));}
    }abstract class Graph{// 属性private double width;private double length;// 有参构造public Graph(double width, double length) {this.width = width;this.length = length;}public double getWidth() {return width;}public double getLength() {return length;}// 方法,周长abstract public double getPerimeter();// 方法,面积abstract public double getArea();}class Rectangle extends Graph{// 手动调用父类的有参构造Rectangle(double width, double length){super(width, length);}// 重写public double getPerimeter(){return 2 * (getWidth() + getLength());}public double getArea(){return getWidth() * getLength();}}class Square extends Rectangle{// 调用父类的有参构造Square(double width){super(width, width);}
    }class Circular extends Graph{public Circular(double r) {super(r,r);}public double getPerimeter(){return 2 * getWidth() * 3.14;}public double getArea(){return 3.14 * getWidth() * getWidth();}
    }
    

java基础(三):java面向对象OOP相关推荐

  1. java的特征多态,java基础(三)—–java的三大特征之多态

    正文 面向工具编程有三大特征:封装.继续.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也珍爱了数据.对外界而已它的内部细节是隐藏的,露出给外界的只是它的接见方式. ...

  2. Java基础教程:面向对象编程[2]

    Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...

  3. java基础入门-02-【面向对象】

    Java基础入门-02-[面向对象] 8.面向对象 8.1. 类和对象 8.1.1 类和对象的理解 8.1.2 类的定义 8.1.3 对象的使用 8.1.4 学生对象-练习 8.2. 对象内存图 8. ...

  4. java基础总结-java技术栈快速复习

    java基础 java基础概念 java概述和语言背景 java语言是没有sun公司(Stanford University Network:斯坦福大学网络)在1995年推出的计算机语言 java之父 ...

  5. Java 基础学习-Java语言概述

    Java 基础学习 第一章 Java语言概述 回顾java基础知识,进行整理记录. 文章目录 Java 基础学习 前言 一. Java语言发展史(了解) 二.Java语言跨平台原理(理解) 三.JRE ...

  6. Java基础:Java抽象接口

    在Java中,一个没有方法体的方法应该定义为抽象方法,而如果一个类中含有抽象方法,则该类必须定义为一个抽象类.接口是功能的集合,同样可看做是一种特殊的数据类型,是比抽象类更为抽象的类,接口只描述所应该 ...

  7. Java 基础-01 Java语言入门

    文章目录 Java 基础-01 Java语言入门 1.计算机基本概念 1.1 计算机概述 1.2 计算机组成 1.3 CPU.内存与硬盘 2.软件基本概念 2.1 软件概述 2.2 人机交互方式 2. ...

  8. 【Java基础】· Java基本语法:程序流程控制习题总结

    写在前面 Hello大家好, 我是[麟-小白],一位软件工程专业的学生,喜好计算机知识.希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!! ...

  9. 黑马程序员:Java基础总结----Java语言编程规范

       黑马程序员:Java基础总结        Java语言编程规范:参考自SUN公司文档  ASP.Net+Android+IO开发..Net培训.期待与您交流!  I.   排版规范 A.  规 ...

  10. java基础之java类型

    系列文章目录 java基础之java类型 文章目录 系列文章目录 基本类型 自动类型提升 引用类型 基本类型 整型 Byte 8位 -2^7~2^7-1 默认值0 Short 16位 -2^15~2^ ...

最新文章

  1. 基本数据类型转换 || 自动类型转换与强制类型转换
  2. sql 精读(二) 标准 SQL 中的编号函数
  3. Lucene系列-facet--转
  4. java preparedstatement 关闭_java - 如果基础连接已关闭,为什么isClosed()方法对PreparedStatements不返回true? - 堆栈内存溢出...
  5. git 提交文件_git原理与实战
  6. 西门子300硬件升级包下载_实例讲解博途编程实现S7300与西门子触摸屏通讯
  7. 手机图形计算器matlab,Mathlab图形计算器下载
  8. Linux下Tomcat中文乱码解决
  9. python的数据正态性检验
  10. c语言逻辑运算符组合,C语言的逻辑运算符
  11. 关于golang导包的大小写敏感问题
  12. 制作flash动画心得
  13. 用LoopBack接口配置EBGP邻居
  14. WIFI6 芯片厂商制程工艺
  15. Java基础 DAY17
  16. win10下解决谷歌浏览器点击安装包无反应
  17. 相约上海,百家公司齐聚SDCC 2017·上海站,约吗?(附名单及参会提醒)
  18. 编译安装apache2.2对应的mod_proxy_fcgi.so模块步骤,apache进行fcgi通信需要加载该模块
  19. BuildR Procedural Building Generator使用教程-建筑建模
  20. 数据结构——线性表知识思维导图

热门文章

  1. Linux内核UDP收包为什么效率低?能做什么优化?
  2. Scikit入门指南
  3. 安装scikit-learn问题
  4. MATLAB读取数据文件
  5. IT是什么行业?就业前景怎么样
  6. Linux检测ip变动
  7. csgo服务器搭建(linux)
  8. ORA-01017: invalid username/password; logon denied ORA-02063: 紧接着line(源于DBLINKN~~~)
  9. “工业互联网+安全生产”,提升工业企业安全水平
  10. 狂神说docker 常用命令笔记