面向对象(二)[Java语言基础](2013/11/28-day03课程笔记)
继承:表示父子概念的关系, XXX类型是XXX的一种
语法:
1) extends(扩展)关键字,子类型(Sub Class)是对父类型
的扩展
2) 父类型(超类 Super Class)的属性和方法,被子类型继承可以继承的才能继承,
3)构造器不能继承
4) 私有方法不能继承
5) 子类可以重写从父类型"继承的方法"!从写是为了修改!
注意:私有方法不可重写
多态
继承以后,父类型变量引用的子类型个体就是多种多样的
执行方法时候,也会出现多种多样的结果(重写).
月饼是多种多样的
电话是多种多样的
四格方块是多种多样的
...
Java 的关键字,不包括: true, false,null!
true, false, null 是字面量
1 Java 方法的参数传递方式
Java只有一种参数参数传递规则:基于值的传递!
变量的值:两种情况
1) 基本类型变量的值,是直接值
int a = 5;//变量a在内存中的值是5
int b = a;
b = 8;
2) 引用类型变量的值,是一个地址值,是被引用对象的首地址
引用类型通过这个地址间接引用对象.
int[] ary = {5,6};//ary的值是数组的首地址.
int[] ary2 = ary;//将ary的值(地址)赋值给ary2
//ary2 和 ary是同样的地址,引用同一个数组对象
ary2 = null;//修改的是ary2变量的值,没有修改数组{}
package day03;
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) {
//变量的赋值, 修改变量的值
int a = 5;
int b = a;
b = 8;
System.out.println(a);//5
int[] ary = { 5, 6 };// ary的值是数组的首地址.
int[] ary2 = ary;// 将ary的值(地址)赋值给ary2
// ary2 和 ary是同样的地址, 引用同一个数组对象
System.out.println(Arrays.toString(ary));
System.out.println(Arrays.toString(ary2));
ary2 = null;// 修改的是ary2变量的值, 没有修改数组{}
System.out.println(Arrays.toString(ary));
System.out.println(Arrays.toString(ary2));
}
}
package day03;
/**
* Java 方法的参数传递方式
Java 只有一种参数参数传递规则: 基于值的传递!
*/
import java.util.Arrays;
public class Demo02 {
public static void main(String[] args) {
Koo koo = new Koo();
int a = 5;
koo.t(a);//a实际参数(实参) 参数传递是变量的a值
System.out.println(a);
int[] ary = {5,6};
koo.t(ary);
System.out.println(Arrays.toString(ary));
//代码的执行结果: A B C.null D.[5,6]
}
}
class Koo{
public void t(int b){//形式上的参数(形参)
//方法参数传递: 是实参到形参传递, 是值的传递
//就是变量值的复制, 修改形参的值, 不影响实参的值
b=8;//方法中改变变量的值,
}
public void t(int[] b){
//b = null;//new int[]{6,7}
b[0]++;
}
}
2 Java 类的初始化过程
package day03;
/**
* 1 构造器不能继承
* 2 子类一定调用父类构造器
* 2.1 Java 默认情况下, 子类构造器自动调用父类无参构造器
* 2.2 如果父类没有无参是构造器, 必须使用super()在子类构造器中调用父类构造器.
* super(8) 必须用在子类构造器的第一行!
*/
public class Demo04 {
public static void main(String[] args) {
new Sub();//证明:子类构造器自动调用父类无参构造器
//选择输出结果: A B C.无 D.Super()
}
}
class Super{
public Super() {
System.out.println("Super()");
}
}
class Sub extends Super{
// public Sub() {
// super();
// }
}
public class Demo05 {
public static void main(String[] args) {
new Ioo();
}
}
class Hoo{
public Hoo(int a) {
System.out.println("Hoo(int)");
}
}
//class Ioo extends Hoo{}//编译错误, 父类没有无参构造器
class Ioo extends Hoo{
//public Ioo() {}//编译错误, 父类没有无参构造器
public Ioo(){
//super();//编译错误
super(8);//在子类构造器中调用父类有参数构造器
}
}
package day03;
/**
* 对象的实例化过程
**/
public class Demo03 {
public static void main(String[] args) {
Foo foo = new Foo();
System.out.println(foo.a+","+foo.b+","+foo.c);
}
}
class Foo extends Goo{
int c = 8;
public Foo(){super();/*属性初始化*/a=8;b=6;c=10;}
}
class Goo extends Xoo{
int b = 3;
public Goo(){super();/*属性初始化*/a=6;b=9;}
}
class Xoo{
int a = 1;
public Xoo(){/*属性初始化*/a=5;}
}
3 造型
package day03;
/**
* 造型: 父类型变量引用子类型实例
* Number: 数
* |-- Integer 整数
* |-- Double 浮点数
* |-- Long
*/
public class Demo06 {
public static void main(String[] args) {
//造型: 自动类型转换, 子类到父类型的转换, 小到大
Integer i = new Integer(5);
Double d = new Double(5.5);
Numbern;
n = i;//将引用i造型为Number类型
n = d;
//强制类型转换, 大到小
//成功的转换
Double x = (Double)n; //强制转换为double
//不能成功的转换
//Integer y = (Integer)n;//会发生运行异常
//instance 实例 of 的,
//如果 n 是 Integer 的实例(类型检查)
if(n instanceof Integer){
Integerz = (Integer)n;//类型安全的转换
}
}
}
4 子类定义父类相同的属性
1) 属性绑定到变量的类型
2) 方法是动态绑定到对象的类型
3) 一般不建议在子类中声明与父类的同名属性
package day03;
/**
* 父子类型具有相同属性, 的访问规则
* 人
* |--骗子
* 1) 属性绑定到变量的类型
* 2) 方法是动态绑定到对象的类型
* 3) 一般不建议在子类中声明与父类的同名属性
*/
public class Demo07 {
public static void main(String[] args) {
Cheater c = new Cheater();
Person p = c;
System.out.println(c.name+","+p.name);
p.whoru();
c.whoru();
}
}
class Person{
String name = "灰太郎";
public void whoru(){System.out.println(name);}
}
class Cheater extends Person{//骗子也是人呀
String name = "喜洋洋";
public void whoru(){System.out.println(name);}
}
5 重载与重写
区别
调用规则
重载:
1) 类中方法名相同,参数列表不同的方法.
2) 根据方法名和参数变量类型,调用重载方法
3) 重载的方法是功能相似的方法
重写:
1) 在子类中"修改"父类的方法.
2) 子类中声明与父类一样的方法
2.1 方法名一样
2.2 参数类型列表一样
2.3 修饰词可以扩大
2.4 异常可以声明的更具体(子类型)以后讲
3) 动态绑定到对象的类型,调用对象类型的重写方法
package day03.pm;
/**
重载:
1) 类中方法名相同, 参数列表不同的方法.
2) 根据方法名和参数变量类型, 调用重载方法
3) 重载的方法是功能相似的方法
重写:
1) 在子类中"修改"父类的方法.
2) 子类中声明与父类一样的方法
2.1 方法名一样
2.2 参数类型列表一样
2.3 修饰词可以扩大
2.4 异常可以声明的更具体(子类型) 以后讲
3) 动态绑定到对象的类型, 调用对象类型的重写方法
*/
public class Demo08 {
public static void main(String[] args) {
Super s = new Sub();
Goo goo = new Goo();
goo.t(s);//参数s的类型是Super, t(Super)
}
}
class Super{
public void t(){System.out.println("Super.t()");}
}
class Sub extends Super{
public void t(){System.out.println("Sub.t()");}
}
class Goo{
public void t(Super s){
System.out.println("t(Super)");s.t();
}
public void t(Sub s){
System.out.println("t(Sub)");s.t();
}
}
电话 (父类型 )功能:打电话
|-- 智能手机子类型:拍照
电话一部电话;
访问电话的方法
智能手机 一部智能手机;
访问智能手机的方法
public void 使用电话(电话 phone){
//只能按照电话的功能操作电话!
//要求拍照是不合理的要求!
}
package day03.pm;
//变量是什么类型, 才能调用相应的属性和方法
public class Demo10 {
public static void main(String[] args) {
Foo foo = new Koo();
foo.f1();//拨打
//foo.f2();//编译错,在Foo类型上没有定义f2()//拍照
}
}
class Foo{//电话
public void f1(){//拨打
System.out.println("Foof1");
}
}
class Koo extends Foo{//智能电话
public void f1(){//拨打
System.out.println("Koof1");
}
public void f2(){//拍照
System.out.println("Koof2");
}
}
Java中的访问控制
可见/访问性 | 在同一类中 | 同一包中 | 不同包中 | 同一包子类中 | 不同包子类中 |
public | yes | yes | yes | yes | yes |
protected | yes | yes | no | yes | yes |
package | yes | yes | no | yes | no |
private | yes | no | no | no | no |
package day03.pm;
import day03.pm.sub.Moo;
/**
* Demo09 与 Noo 是在同一包中声明类
* 在Demo09 中可以访问Noo的公有和同包资源(属性和方法)
*/
public class Demo09 {
public static void main(String[] args) {
Noo noo = new Noo();
System.out.println(noo.a);
System.out.println(noo.b);
System.out.println(noo.c);
noo.c = 8;
//System.out.println(noo.d);//编译错误,d不可见
System.out.println(noo.getD());//读取d
//Demo09 与 Moo 不在同一个包中
Moo moo = new Moo();
System.out.println(moo.a);
//System.out.println(moo.b);//编译错误
//System.out.println(moo.c);//编译错误
//System.out.println(moo.d);//编译错误
System.out.println(moo.getD());
}
}
class Poo extends Moo{
public void test(){
System.out.println(super.a);
System.out.println(b);
//System.out.println(c);//编译错误
//System.out.println(d);//编译错误
}
}
class Noo{
public int a = 1;
protected int b = 2;
/*默认的*/int c = 3;
private int d = 4;
public int getD() { return d;}
}
package day03.pm.sub;
/*与Demo09不在同一包中,体现出protected 与默认的区别*/
public class Moo {
public int a = 1;
protected int b = 2;
/*默认的*/int c = 3;
private int d = 4;
public int getD() { return d;}
}
方法签名:识别方法的名字
方法签名=方法名+参数类型列表