面向对象编程学习笔记
一.灵活对应——多态性
多态是指对于一种服务功能,可以具有不同的实现方式,即多种形态。多态形象的描述了现实世界的复杂形态,使程序具有良好的扩展性。在继承的基础上,方法的重载是实现多态的方式之一。
重点:Object类的toString()与equals(Object obj)方法。
1. toString方法,其返回值为String类型,描述当前对象有关信息。如果直接打印某对象的引用,则默认调用这个对象的toString()方法,默认打印内容包含这个引用指向的内存地址。但是可以根据用户自定义,重写toString方法。
2. object类的equals方法为:
x.equals(y)
,当x和y指向同一地址返回ture,否则返回false。即:比较的是两个对象的引用。
3. String类的equals()方法比较的是当前对象的字节符内容。
二.多态性是由封装性和继承性引出的面向对象的程序的另一个特征。
多态性的表现:
方法角度:方法的重载和重写。
从对象的角度:分为两种。
向上转型:子类对象 ->父类对象(程序自动完成)
格式:父类 父类对象 = 子类实例
说明:向上转型后,因为操作的是父类对象,所以无法找到在子类中定义的新方法;但是如果子类重写了父类的某个方法,则调用的是重写后的方法。
Student stu=new Student(); Person per=stu; // 向上转型 per.say();
向下转型:父类对象 -> 子类对象(必须明确指出要转变的子类类型)
格式:子类 子类对象 = (目标对象)父类实例
说明:向下转型前,先要向上转型。
Person per=new Student(); // 向上转型 Student stu=(Student)per; // 向下转型 stu.learn();
intanceof关键字:在java中可以使用intanceof关键字判断一个对象是否**属于**一个类的实例。其中**属于**两层含义,一是类似“照妖镜”的作用,看是否属于某一个类;二是可以用于自己对象查看自己的类。
Person p=new Student(); System.out.println(p instanceof Person); // 判断p是否是Person类型
final关键字:在java中声明类、属性和方法时,可以使用final来修饰。
注意:1.final修饰变量(成员变量或局部变量),则成为常量,只能赋值一次。
private final String NAME="张三";
2.final修饰方法,则该方法不能被子类重写。
public final void walk(){ System.out.println("人用两条腿走路~~~"); //final修饰方法 }
3.final修饰类,该类不能别继承。
三.抽象类
定义:用abstract修饰的类即为抽象类。
格式:
abstract class 抽象类名{ }
1. 抽象类不能被实例化,必须被继承。抽象方法必须被重写,生成它的子类。由abstract修饰的方法就是抽象方法,抽象方法没有方法体。
public abstract class Animal { private String name; private String food; public Animal(){ } public Animal(String name, String food) { this.name = name; this.food = food; } public abstract void eat(); // 抽象方法只声明,不实现 }
2. 抽象类不一定要包含抽象方法,若类中包含了抽象方法,则该类必须被定义为抽象类。若子类也为抽象类,则可以不用重写父类抽象方法。
// 如果子类也是一个抽象类,则可以不用重写父类的抽象方法 public abstract class Tiger extends Animal{ public abstract void run(); }
四.接口
定义:是抽象类和常量值的定义集合。(没有构造方法)接口是一种“标准”,“契约”。
从本质上讲:接口是一种特殊的抽象类。这种抽象类只能包括常量和方法 的定义,而没有变量和方法的实现。
声明:
[public] interface interfaceName [extends listofsuperInterface]{
}
接口体:常量定义
type Name = value;
该常量被实现该接口的多个类共享,自带public,static,final属性。
/** * 飞翔接口 */ public interface Fly { public static final int SPEED=200; // 常量 public abstract void fly(); }
接口的实现类:与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口。
public class Kite implements Fly{ @Override public void fly() { System.out.println("风筝飞翔..."); } }
五.字符串相关类
String类
(1)String代表字符串类型,字符串的内容本身不可改变,字符串存在于“字符串常量池”中。
Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "Hello";,另一种就是使用new这种标准的构造对象的方法,如String str = new String("Hello");,这两种实现其实存在着一些性能和内存占用的差别。这一切都是源于JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池。
下图展示使用new这种标准的构造对象的方法,在底层是怎么实现的:
2.String类常用的方法
(1)public String(byte[] bytes)
使用平台的默认字符集解码,将字节数组转换为字符串
(2)public String(byte[] bytes,Charset charset)
使用指定字符集解码,将字节数组转换为字符串
(3)public char charAt(int index)
根据索引位置获取字符串中的某个字符
(4)public boolean contains(CharSequence s)
判断当前对象代表的字符串是否包含参数字符串内容
(5)public boolean equals(Object anObject)
判断字符串内容是否相同
(6)public byte[] getBytes()
将字符串转换为字节数组
(7)public int indexOf(String str)
返回参数字符串在当前字符串中的索引位置
(8)public int lastIndexOf(String str)
从后往前找参数字符串,返回参数字符串在当前字符串中的索引位置
(9)public int length()
返回当前字符串的长度
(11)public String toLowerCase()
将字符串转换为小写
(12)public String toUpperCase()
将字符串转换为大写
(13)public char[] toCharArray()
将字符串转换为字符数组
(14)public String substring(int beginIndex)
从beginIndex索引位置开始,到字符串末尾,截取字符串
(15)public String substring(int beginIndex,int endIndex)
从beginIndex索引位置开始,到endIndex-1,截取字符串
(16)public String trim()
返回一个字符串,这个字符串删除了前导和尾随空格
(17)public String[] split(String regex)
通过指定的正则表达式拆分字符串,将拆分后的结果作为一个字符串数组返回
3.StringBuffer:
Stringbuffer代表可变的字符序列。
工作原理:预先申请一块内存,存放字符序列,如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。是可变对象,这个是与String最大的不同(如果连续操作String对象,则会产生大量的“垃圾”,而且“断开-连接”很频繁。)
4.StringBuilder类:
StringBuilder和StringBuffer功能几乎是一样的,只是 StringBuilder是线程不安全的,StringBuffer是线程安全的。
六.内部类
定义:在类的内部定义另一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而Outer则称为外部类。
public class Outer {
private String name="中国";
public void func(int x){
public class LocalInner{
public void method(){
System.out.println("局域内部类访问外部类的属性:"+name);
System.out.println("局域内部类访问包含其方法的参数"+x);
}
}
}
}
使用内部类的好处:(1)可以方便地访问外部类的私有属性。(2)减少了类文件编译后的产生的字节码文件的大小。
缺点:使程序结构不清楚。
成员内部类:(1)不能定义static变量。
(2)持有外部类的引用。
(3)格式(外部实例化成员内部类):外部类.内部类 内部类对象=外部类实例.new 内部类();
public class Outer {
private String name="中国人";
// 成员内部类
class MemberInner{
public void method(){
System.out.println("内部类可以访问外部类的私有属性:"+name);
}
}
public MemberInner getMemberInstance(){
return new MemberInner();
}
}
2.静态内部类:如果一个内部类使用static声明,则此内部类就称为静态内部类,其实也相当于外部类。
可以通过外部类.内部类来访问。 v静态内部类不会持有外部类的引用,创建时可以不用创建外部类对象 v静态内部类可以访问外部的静态变量,如果访问外部类的非static 成员变量必须通过外部类的实例访问 v外部实例化静态内部类对象的格式:外部类.内部类 内部类对象= new 外部类.内部类();
public class Outer {
private String name="中国";
private static int population=14;
static class StaticInner{
public void method(){
System.out.println("静态内部类直接访问外部类的static属性:"+population);
Outer out=new Outer();
System.out.println("在静态内部类中通过外部类对象访问非static属性:"+out.name);
}
}
public static StaticInner getStaticInner(){
return new StaticInner();
}
}
3.局部内部类:局域内部类是定义在一个方法中的内嵌类,所以类的作用范围仅限于该方法中,而类生成的对象也只能在该方法中使用。局域内部类不能包含静态成员。
public class Outer {
private String name="中国";
public void func(int x){
class LocalInner{
public void method(){
System.out.println("局域内部类访问外部类的属性:"+name);
System.out.println("局域内部类访问包含其方法的参数"+x);
}
}
new LocalInner().method(); // 在局域内部类所在的方法中实例化局域内部类对象,并调用其方法
}
}
4.匿名内部类:如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类。
没有名字的内部类 这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿 名内部类就比较合适。
public class TestAnonumity {
public static void main(String[] args) {
Jumping j=new Jumping(){
@Override
public void jump() {
System.out.println("跳...");
}
};
j.jump();
}
}
转载于:https://blog.51cto.com/13531757/2055205