//面向对象_继承_概述---单继承_多继承。
//描述学生。
/*
class Student
{
//属性。
String name;
int age; //行为:
void study()
{
System.out.println("good good study");
}
} class Worker
{
//属性:
String name;
int age; //行为;
void work()
{
System.out.println("hard work");
}
}
*/ /*
为了提高代码的复用性,只建立一份代码就可以了。
一个类只要和另一个类产生关系就可以了。
关系:继承。
发现了获取到所需内容的同时也获取到不该具备的内容。
为什么?
发现原来这两个类之间根本就不存在继承关系。 怎么解决呢?
找到学生和工人的共性类型。将需要提供复用的代码进行抽取。
定义到一个共性的类中。
Person name age. 怎么在代码体现中,让学生和Persong产生关系呢?
只要通过关键字extends(继承),就可以了。
*/
class Person
{
//属性:
String name;
int age;
} class Student extends Person//学生继承了Person,学生就是子类,Person就是父类(基类。超类)
{
//行为:
void study()
{
System.out.println("good good study");
}
} class Worker extends Person
{
//行为;
void work()
{
System.out.println("hard work");
}
} /*
面向对象的另一个特征:继承。
好处:提高了代码的复用性。让类和类产生了关系,给另一个特征。多态提供了前提。 什么时候定义继承?
必须保证类与类之间有所需(is a)关系.xxx是zzz中的一种。
学生是人中的一种。
苹果是水果中的一种。
狗是犬科中的一种。 在Java中继承的体现。
Java允许单继承。不直接支持多继承。将多继承进行其他方式的体现。
单继承:一个子类只能有一个父类。
多继承:一个子类可以有多个父类。 看上去,多继承很厉害!为什么?
class Fu1
{
void show1()
{}
} class Fu2
{
void show2()
{}
}
//多继承。
class Zi extends Fu1,Fu2
{ } Zi z = new Zi();
z.show1();
z.show2();
//问题随之而来,
万一多个父类具备了相同的功能呢?
class Fu1
{
void show()
{
sop("fu1 show run");
}
} class Fu2
{
void show()
{
sop("fu2 show run");
}
}
//多继承。
class Zi extends Fu1,Fu2
{ }
Zi z = new Zi();
z.show();//调用就会产生不确定性。所以java保留了多继承的好处。
//改良了它的弊端,用多实现来体现。用多实现来体现。
//即将学到。
----------------------------------
java中还支持多重继承。
class A
{}
class B extends A
{}
class C extends B
{} //形成继承体系。 学习继承体系时,应该参阅顶层的类中的内容。
了解这个体系的基本功能。 使用这个体系功能,需要创建最子类的对象。
看顶层,建底层。 */
class ExtendsDemo
{
public static void main(String[] args)
{
Student stu = new Student();
stu.name = "xiaoming";
stu.age = 12;
stu.study();
}
}
 //面向对象_继承_子父类中成员变量的特点。
/*
继承出现后,在代码中的体现。 重点在于成员的体现:
1,成员变量。重点明确原理。
特殊情况:
子父类中定义了一模一样的成员变量。
都存在于子类对象中。
如何在子类中直接访问同名的父类中的变量呢?
通过关键字super来调用。 super和this的用法很相似。
this代表的是本类对象的引用。
super代表的是父类的内存空间。 注意:这种情况开发见不到。因为父类一旦描述完了属性,
子类直接使用就可以了。 2,成员函数。
3,构造函数。
*/ //父类
class Fu
{
/*private int num1 = 3;*///父类中私有的内容子类不可以直接访问。
int num = 3;
} class Zi extends Fu
{
/*int num2 = 4;*/
int num = 4;
void show()
{
// System.out.println("num1="+num1);
// System.out.println("num2="+num2);
System.out.println("fu num="+super.num);
System.out.println("zi num="+this.num);
System.out.println(this);
}
}
class ExtendsDemo
{
public static void main(String[] args)
{
Zi z = new Zi();
// System.out.println(z.num1);
// System.out.println(z.num2);
z.show();
}
}
 /*
子父类中成员函数的特点。
特殊情况:
子父类中定义了一模一样的函数。
运行的结果是子类的函数在运行。
这种情况在子父类中,是函数另一个的特性,Override 重写(覆盖,复写) 重写什么时候用?
举例:
//描述手机
class Phone
{
//打电话。
void call()
{} //来点显示。
void show()
{
System.out.println("电话号码");
}
} Phone p = new Phone();
p.show(); //随着电话的升级,只显示号码不爽,希望显示姓名,大头贴等。
修改源码,虽然费劲,但是可以解决问题,但是不利于后期的维护和扩展。
为了扩展方便,新功能是不是新的电话具备呢?
单独描述,单独封装。新电话也是电话中的一种,继承。直接获取父类中的功能。
但是新电话的来电显功能已经变化了。需要重新定义。
那么定义一个新功能合适吗?比如NewShow,不合适,因为父类已经将来点显功能定义了。
子类完全不需要重新定义新功能,直接用就可以了,如果子类的来显功能内容不同。
只需要保留来显功能,定义子类的内容即可,这就是重写的应用。
class NewPhone extends Phone
{
void show()
{
//System.out.println("电话号码");
super.show();//如果还需要父类中原有的部分功能,可以通过super调用。
sop("姓名");
sop("大头贴");
}
} 重写的注意事项:
1,子类覆盖父类,必须保证权限要大于或者等于父类的权限。(private除外,因为子类
中不能直接访问父类中的private。)
Fu:
void show(){} Zi:
void show(){} 2,静态覆盖静态。 写法上注意:不行一模一样:函数的返回值类型 函数名 函数的参数列表都要一样。
*/
class Fu
{
void show()
{
System.out.println("fu show1 run");
}
}
class Zi extends Fu
{
static void show()
{
System.out.println("zi show2 run");
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show(); }
}
 /*
子父类中构造函数的特点。
当子父类中都有构造函数时,发现结果为:
Fu constructor run
zi constructor run
先执行了父类的构造函数,再执行子类中的构造函数。
为啥呢?
因为子类中的所有的构造函数中的第一行都有一句隐式额语句Super();
//默认调用的是父类中空参数的构造函数。
子类中构造函数为什么有一句隐式的super呢?
原因:子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去
执行父类的初始化动作。
才可以更方便子类使用。 当父类中没有空参数构造时,子类的构造函数必须显示的super语句指定
要访问的父类中构造函数。 这就是传说中的子类实例化过程。 细节:
1,如果子类的构造函数第一行写了this调用了本类的构造函数,那么super调用父类的
语句还有吗?
没有的,因为this()或者super(),只能定义在构造函数的第一行,因为初始化动作要先执行。 2,子类构造函数里有super,那么父类构造函数有没有super呢?
是有的,记住:只要是构造函数默认第一行都是super();
父类的父类是谁呢?super 调用的到底是谁的构造函数呢?
Java体系在设计时,定义了一个所有对象的父类Object. 总结:
类中的构造函数默认第一行都由隐式的super语句,在访问父类中的构造函数。
所以父类的构造函数既可以给自己的对象初始化,也可以给自己的子类对象初始化。 如果默认的隐式super语句没有对应的构造函数,必须在构造函数中通过this或者super
的形式明确要调用的构造函数。 问题:
1,this 语句和super语句是否可以在同一个构造函数中出现呢?不行:因为必须定义在第一行。
2,为什么要定义在第一行呢?因为初始化动作要先执行。
*/ class Fu extends Object
{
int count = 3;
//Fu(){}
Fu()
{
//super();
//显示初始化。
System.out.println("Fu constructor run..A.."+count);
}
Fu(int x)
{
//显示初始化。
System.out.println("Fu constructor run..."+x);
}
} class Zi extends Fu
{
Zi()
{
System.out.println("zi constructor run..C..");
}
Zi(int x)
{
this();
System.out.println("zi constructor run..."+x);
}
}
class ExtendsDemo
{
public static void main(String[] args)
{
//New Zi();
new Zi(6);
new Student("lisi",21);
}
} /* class Fu
{
Fu()
{
System.out.println("Fu constructor run..A..");
}
Fu(int x)
{
//显示初始化。
System.out.println("Fu constructor run..B..");
}
} class Zi extends Fu
{
Zi()
{
//super();
System.out.println("Fu constructor run..C..");
}
Zi(int x)
{
//super();
System.out.println("Fu constructor run..D..");
}
}
class ExtendsDemo
{
public static void main(String[] args)
{
new Zi();
new Zi(6);//打印结果是A C A D.
}
} */ //子类的实例化过程的应用。也是super调用的应用。
//什么时候用super调用父类中的构造函数,只要使用父类的指定初始化动作,
//就在子类中使用super()调用就可以了。
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
class Student extends Person
{
public Student(String name,int age)
{
//调用父类,使用父类的初始化动作。
super(name,age);
} } class Worker extends Person
{
public Worker(String name,int age)
{
//调用父类,使用父类的初始化动作。
super(name,age);
}
}
 //final关键字。
/*
继承的弊端:打破封装性。
不让其他类去继承该类,就不会有重写。
怎么能实现呢?通过java中的关键字来实现。final(最终化) 【final】
是一个修饰符。可以修饰类,方法,变量(成员变量,局部变量,静态变量)
【特点】
1,final修饰的类是一个最终类,不能再派生子类。
如果类中出现部分可以重写,部分不可以?怎么办?只要让指定的方法最终化就可以了。
2,final修饰的方法是最终方法,不可以重写。
3,fianl修饰变量是一个常量。只能被赋值一次。
【什么时候需要在程序中定义final常量呢?】
当程序中一个数据使用时是固定不变的,这时为了增加阅读性,可以给该数据起个名字。
这就是变量,为了保证这个变量的值不被修改,加上final修饰,这就是一个阅读性很强的
常量。书写规范,被final修饰的常量名所有的字母都是大写的。如果由多个单词组成,单词
之间用下划线连接。
*/
/*final*/ class Fu
{
/*final*/ void show()
{
//调用到一些系统的功能。
//功能的内容是不可以改变的。
}
} class Zi extends Fu
{
static final int number = 9;//这个编译会失败,final修饰的变量必须赋初值。
static final double PI = 3.14;//为了访问方便,直接用static修饰,可以直接用类名调用。
//覆盖
void show()
{
final int count = 21;
//count = 2;//失败。
System.out.println(count);
}
} class FinalDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
 /*
描述狗,行为,吼叫。
描述狼,行为:吼叫。
发现他们之间有共性,可以进行向上抽取。
当然是抽取它们的所属共性类型,犬科。
犬科这类事物,都具备吼叫行为。但是具体怎么叫,是不确定的,是由具体的子类来
明确的。
这些不具体的功能,需要在类中标识出来,通过java中的关键字来体现。 定义了抽象函数的类也必须别abstract修饰。 抽象类,在描述事物时,没有足够的信息描述一个事物,这时该事物就是抽象事物。
*/ /*
【抽象类的特点】
1,抽象类和抽象方法都需要被abstract修饰。
抽象方法一定要定义在抽象类中。
2,抽象类不可以创建实例。原因就在于调用抽象方法没意义。
3,只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。
否则,该子类还是一个抽象类。 之所以继承,更多的是在思想上,是面对共性类型操作会更简单。 【细节问题】
1,抽象类一定是一个父类。
是的,因为是不断向上抽取而来的。 2,抽象类中是否有构造函数。
有,虽然不能给自己的对象初始化,但是可以给自己的子类对象初始化。
抽象类和一般类的异同点:
相同:
1,它们都是用来描述事物的。
2,它们之中都可以定义属性和行为。
不同:
1,一般类可以具体的描述事物,
抽象类描述事物的信息不具体。
2,抽象类中可以多定义一个成员,抽象汉。
3,一般类可以创建对象,而抽象类不能创建对象。 3,抽象类中是否可以不定义抽象方法。
是可以的。那这个抽象类的存在到底有什么意义呢?仅仅是不让不让该类创建对象。 4,抽象类关键字不可以哪些关键字共存。
1,final. 被final修饰的类是最终类,不能被继承,而抽象类就是要被子类继承的。
2,private. 被private修饰的方法,其子类无法直接访问,而抽象的方法就是要让子类覆盖的。
3,static. 被static修饰的方法要随着类的加载而加载,且可以直接由类名调用。 */ abstract class 犬科 //extends Object
{
abstract void 吼叫();//抽象函数,需要abstract修饰。并分号;结束
} //代码体现。
class Dog extends 犬科
{
void 吼叫()
{
System.out.println("汪汪汪汪");
}
} class Wolf extends 犬科
{
void 吼叫()
{
System.out.println("嗷嗷嗷嗷");
}
} class AbstractDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
 /*抽象类联系
需求:公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了姓名,工号,薪水,还有奖金,工作内容。
对给定的需求进行数据建模。 在问题领域中先找寻其中的涉及的对象。
程序员:
属性:姓名,工号,薪水。
行为:工作。 项目经理:
属性:姓名,共号,薪水。
行为:工作。 这些对象是否有关系呢?因为发现了它们之间的共性,应该存在着关系。
可以将他们的共性向上抽取到共性类型,员工。
员工:
属性:姓名,工号,薪水。
行为:工作。
发现员工的工作内容本身就不具体,应该是抽象的,由具体的子类来体现。 */ abstract class Employee
{
private String name;
private String id;
private double pay; /**
构造一个员工对象,一初始化就具备三个属性。
*/ Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
} /**
工作行为:
*/
public abstract void work();
} //具体的子类实现,程序员:
class Programer extends Employee
{
Programer(String name,String id,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("code....");
}
} //具体的子类,经理:
class Manager extends Employee
{
//特有属性。
private double bouns;
public Manager(String name,String id,double pay,double bouns)
{
super(name,id,pay);
this.bouns = bouns;
} public void work()
{
System.out.pritnln("work");
}
}
class AbstractTest
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
/*
抽象类中是可以定义抽象方法的,当一个抽象类中方法全是抽象的,
这时,可以通过另一种特殊的形式来体现。 不再用class来定义,用接口来表示。 接口该如何定义呢?
interface abstract class Demo
{
abstract void show1();
abstract void show2();
} */ /*
接口中的成员已经被限定为固定的几种。
【接口的定义格式先介绍两种】
1,定义变量,但是变量必须有固定的修饰符修饰,public static final所以接口中的变量
也称之为常量。
2,定义方法,方法也有固定的修饰符,public abstract
接口中的成员都是公共的。 【接口的特点】
1,接口不能创建对象。
2,子类必须覆盖掉接口中所有的抽象方法后子类才可以实例化。
否则子类是一个抽象类。
*/
interface Demo//定义一个名称为Demo的接口。
{
public static final int NUM = 3;
public abstract void show1();
public abstract void show2();
} //定义子类去覆盖接口中的方法。子类必须和接口产生关系,类与类的关系是继承
//类与接口之间是实现。
class Demoimpl implements Demo //子类实现接口。
{
//重写接口中的方法。
public void show1(){}
public void show2(){}
} /*
【接口最重要的体现】
解决了多继承的弊端。将多继承这种机制在java中通过多实现完成了。 */ /*
interface A
{
void show1();
}
interface B
{
void show2();
}
class C implements A,B//多实现。同时实现多个接口。
{
public void show1(){}
public void show2(){}
}
*/
/*
【怎么解决多继承的弊端呢?】
弊端:多继承时,当多个父类中有相同的功能时,子类调用会产生不确定性。
其实核心原因就在于多继承父类中的功能有主体,而导致调用运行时,不确定运行哪个主体内容。
为什么多实现就解决了呢?
因为接口中的功能都没有方法体,由子类来明确。
interface A
{
void show();
}
interface B
{
void show();
}
class C implements A,B//多实现。同时实现多个接口。
{
public void show(){}
} C c = new C();
c.show();
*/ /*
【基于接口的扩展】
class Fu
{
public void show(){}
}
//子类通过继承父类扩展功能,通过基础扩展的功能都是子类应该具备的基础功能。
//如果子类想要继续扩展其他类中的功能呢?这时可以通过实现接口来完成。 Interface Inter
{
public abstract void show1();
}
class Zi exntends Fu implements Inter
{
public void show1()
{ }
} 接口的出现避免了单继承的局限。
父类中定义的事物的基本功能。
接口中定义的事物的扩展功能。
*/ /*
接口出现后的一些小细节。
1,类与类之间是继承(is a)关系。类与接口之间是实现(like a)关系。
接口与接口之间有关系吗?接口与接口之间是继承关系。
*/
interface InterA
{
void show1();
}
interface InterAA
{
void show11();
}
interface InterB extends InterA,InterAA//接口支持多继承。
{
void show2();
}
class Test implements InterB
{
public void show1(){}
public void show2(){}
public void show11(){}
} class InterfaceDemo
{
public static void main(String[] args)
{
Demoimpl d = new Demoimpl();
d.show1();
d.show2();
}
}
 /*
抽象类中是否可以不定义抽象方法,
是可以的。原因是不让该类创建对象。
*/
interface Inter
{
//定义了四种显示功能。
public void show1();
public void show2();
public void show3();
public void show4();
} //定义子类,要使用第一种显示方式,
class InterImpl1 implements Inter
{
//覆盖show1方法。
public void show1()
{
System.out.println("show1 run");
}
//为了让该类示例化,还需要覆盖其他三个方法,虽然该类用不上。
public void show2(){}
public void show3(){}
public void show4(){}
} //另一个子类需要显示三方法。
class InterImpl3 implements Inter
{
//覆盖show1方法。
public void show3()
{
System.out.println("show3 run");
}
//为了让该类示例化,还需要覆盖其他三个方法,虽然该类用不上。
public void show2(){}
public void show1(){}
public void show4(){}
} /*
出现问题,
为了使用接口中的部分方法,而覆盖了全部的方法。而且每一个子类都要
这么做,复用性差。 将这些不用的方法都单独抽取到一个独立的类中,
让这个类去实现接口,并覆盖接口中的所有方法。
这个类知道这些方法的具体实现内容么?不知道。
所有只能为了后期子类创建对象方便,而进行空实现。
而这时,这个类创建对象有有意义吗?没有意义,这个类创建对象就不需要,直接将其抽象化。
这就是没有抽象方法的抽象类。
*/ abstract class InterImpl implements Inter
{
//实现inter接口中的所有方法。
public void show1(){}
public void show2(){}
public void show3(){}
public void show4(){}
} //如果有子类去使用show1方法。让子类继承实现类就可以。
class InterImpl11 extends InterImpl
{
public void show1()
{
System.out.println("show1 run");
}
}
class
{
public static void main(String[] args)
{
InterImpl1 in1 = new InterImpl1();
in1.show1(); InterImpl3 in3 = new InterImpl3();
in1.show3();
}
}

《day09---继承-抽象类-接口》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. phalcon: (非官方)简单的多模块

    phalcon: [非官方]多模块 配合router使用 例如:我的模块叫做: home 入口文件增加引入: use Phalcon\Mvc\Router; 在自动引入前面增加,自动引入命名空间: / ...

  2. <转>java 快速查找

    [Ct rl+T] 搜索当前接口的实现类 1. [ALT +/]    此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ ...

  3. @ExceptionHandler

    @Controller public class AccessController { /** * 异常页面控制 * * @param runtimeException * @return */ @E ...

  4. @ControllerAdvice

    @ControllerAdvice,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@ControllerAdvice的实现: @Target(ElementTyp ...

  5. 2016年Web前端面试题目汇总

    转载: 2016年Web前端面试题目汇总 以下是收集一些面试中经常会遇到的经典面试题以及自己面试过程中未解决的问题,通过对知识的整理以及经验的总结,重新巩固自身的前端基础知识,如有错误或更好的答案,欢 ...

  6. 移动端的touch事件处理

    简要的探讨一下移动端 touch 事件处理几个坑,以及相应的简单处理方法. click 穿透 假设有个弹出层,上面有个关闭的按钮支持 touchend 触发后关闭,若正好下方有个元素支持 click ...

  7. Django数据库设置

    设置数据库,创建您的第一个模型,得到一个简单介绍 Django的自动生成管理网站. 数据库设置 现在,打开 mysite / settings.py . 这是一个普通的Python模块 模块级变量代表 ...

  8. 从Oracle迁移到Mysql之前必须知道的50件事

    1. 对子查询的优化表现不佳. 2. 对复杂查询的处理较弱 3. 查询优化器不够成熟 4. 性能优化工具与度量信息不足 5. 审计功能相对较弱 6. 安全功能不成熟,甚至可以说很粗糙.没有用户组与角色 ...

  9. PHP Warning: ob_start() : output handler 'ob_gzhandler conflicts with 'zlib output compression'

    安装phpcms过程中,会遇到Warning:  ob_start() : output handler 'ob_gzhandler conflicts with 'zlib output compr ...

  10. iOS开发之内购-AppStore

    本文会给大家详细介绍iOS内购,虽然之前网上也有内购的教程,但是还不够详细,我重新整理出一份教程,希望对大家有所帮助. 基于Xcode7.1.1版本,模拟器iphone6,9.1系统.部分地方直接摘自 ...