主要内容:
1、接口
2、包及访问权限
3、内部类(了解)
4、Object类
5、String类
一、回顾:
1.1 继承:
特点:
单继承
多层继承
最底层类、最顶层类
注意问题:
只能继承非私有成员
Super可以访问父类的构造方法
不能为了部分功能而继承
Is a
This和super
继承中构造方法的关系:
继承中成员变量的关系:就近原则
继承中成员方法的关系:
访问权限:public、protected、friendly(缺省的)、private
final:
1.2 多态:
事物存在多种不同的形态。
前提:
继承
方法重写
父类引用指向子类对象
多态中成员访问
成员变量:编译左,运行左
方法:编译左,运行右
静态方法:编译左,运行左
向上转型:
向下转型:
1.3 抽象类:
特点:
Abstract关键字
不一定有抽象方法
不能实例化
抽象类的子类,要么是抽象类,要么是实现抽象类全部抽象方法的具体类
抽象类成员的特点:
成员变量:常亮、变量。
成员方法:抽象方法——强制要求子类必须做。实例方法——子类可以继承。
构造方法:有构造方法。
Abstract关键字不能与哪些关键字共存?
二、接口:
2.1 接口的定义:
从广义上讲,接口是Application Interface(API),指导说明书。
接口Interface。就是一种规则。
2.2 接口的特点:
接口中只能有抽象方法,不能有实例方法。
接口中的成员变量都会被定义为常量(会默认添加final关键字),必须要初始化。
类实现接口(class XXXX implements XXXXInterface),就必须要重写接口中全部方法(抽象方法)。
接口不能实例化,接口的使用必须要依赖它的实现类。
public interface UserDao { public final String name = "";
// 抽象方法 public abstract void eat();
public abstract void sleep(); } |
public class UserDaoImpl implements UserDao {
// @Override // 注解 public void eat() { System.out.println("过早!"); }
// @Override public void sleep() { // TODO Auto-generated method stub
} } |
public class MyTest { public static void main(String[] args) { UserDao dao = new UserDaoImpl(); // 父类引用指向子类对象 dao.eat(); } } |
2.3 接口成员的特点:
成员变量:只能是常量,并且必须是静态的、公共的、final的。(默认添加修饰符:public static final)
成员方法:只能是抽象方法。(默认修饰符为public abstract)
构造方法:接口没有构造方法。
2.4 接口、类之间的关系:
1、类与类的关系:
继承关系,单继承,多层继承
2、类与接口:
实现关系,可以单实现,也可以多实现
public class UserDaoImpl implements UserDao, UserDao2 {...}
还可以在继承一个父类的同时实现接口。
接口打破了单继承的局限性,接口可以降低层与层之间的耦合性。
3、接口与接口之间的关系:
继承关系,可以是单继承,可以多继承。
2.5 抽象类和接口的区别:
1、成员的区别:
抽象类:
成员变量:可以是变量,也可以是常量
构造方法;有
成员方法:可以抽象,可以非抽象
接口:
成员变量:必须是常量
构造方法:没有
成员方法:必须抽象
2、理念的区别:
抽象类:被继承体现的是”is a”的关系,抽象类中定义的是该继承体系的共性功能。
接口:被实现体现的是”like a”的关系,接口中定义的是该实现体系的扩展功能。
三、包
3.1 包的概述:
包——将字节码文件进行分类存放,对应的是字节码文件的目录。
分级原则:按照功能(增删查改)、按照模块(推荐)
图书管理系统:
按照功能
com.xxxx.add
com.xxxx.delete
com.xxxx.update
com.xxxx.read
按照模块:
com.xxxx.book
com.xxxx.admin
3.2 包的定义
1、包的格式:
package 包名;
多级使用.分开
2、注意事项:
包语句必须放在是程序的第一条可执行的代码
包语句在一个java文件中只能有一个
如果没有package,默认表示无名包。
3.3 带包的类编译和运行:
1、编译时加上-d .
2、使用java指令运行时要带上包名:
3.4 不同包之下内的访问:
3.5 import关键字:
作用:让有包的类对调用者可见,不用写类的完整名称了。
导包的格式:
import 包名.类名;
import 包名.接口名;
如果在一个类中,使用多个同包中的类或接口,使用*代表该包中所以类和接口。import com.xxxx.yyyy.*
package/import/class(interface)的顺序:package->import->class/interface
Package语句必须是第一条可执行语句;
Import必须出现在class/interface语句之前。
3.6 访问权限修饰符:
public
protected
friendly(缺省)
private
3.7 常见的修饰符:
1、修饰符:
权限修饰符:
状态修饰符:static、final
抽象修饰符:abstract
2、类(class)
权限修饰符:public、protected、friendly(缺省的)
状态修饰符:final(意味着该类不能被继承)
抽象修饰符:abstract(抽象类)
3、成员变量:
权限修饰符:public、protected、friendly(缺省的)、private
状态修饰符:static、final
4、构造方法:
权限修饰符:public、protected、friendly(缺省的)、private
使用最多是public
5、成员方法:
权限修饰符:public、protected、friendly(缺省的)、private
状态修饰符:static、final(意味着不能被重写)
抽象修饰符:abstract
6、常用的组合:
成员变量:
变量:private 类型 名称
常量:public static final 类型 名称
成员方法:
public static
public abstract
public final
四、内部类:
4.1 内部类:
定义:在类的内部也可以定义一个类。如果在类Outer的内部再定义一个类叫Inner,那么Inner类就被称为内部类,Outer类被称为外部类。
4.2 内部类的特点:
1、内部类可以直接访问外部类的成员。(包括私有)
2、外部类要访问内部类的成员,必须创建对象。
Outer.Inner inner = new Outer().new Inner();
- 用static声明内部类,这个内部类会变成外部类。这个类就不能访问非静态的外部类成员。
public class Outer { private int num = 100; // 外部类的成员变量
public void print() { System.out.println("外部类的测试方法!"); }
class Inner { // 内部类 int num = 10000; // 内部类的成员变量
public void print() { System.out.println("内部类的测试方法!"); }
public int sum() { return Outer.this.num + num; // Outer.this.num获取外部类成员变量 } }
static class Inner2 { public void test() { // 静态类(或静态方法)不能访问非静态变量和方法 // System.out.println(Outer.this.num); } } }
|
public class MyTest { public static void main(String[] args) { Outer outer = new Outer(); outer.print();
// 外部类要访问内部类的成员,必须创建对象 Outer.Inner inner = new Outer().new Inner(); inner.print(); System.out.println(inner.num); } } |
4.3 在方法中使用内部类:
public class Outer { int score = 95;
public void inst() { final int add = 0; // 局部变量 // 在方法中定义的内部类,只能访问方法中的final修饰的局部变量,因为用final修饰的局部变量相当于一个常量,它的生命周期超出方法的生命周期的 class Inner { public void display() { score += add; System.out.println("成绩:" + score); } } Inner inner = new Inner(); inner.display(); } } |
public class MyTest { public static void main(String[] args) { Outer outer = new Outer(); outer.inst(); } } |
五、Object类:
5.1 Object类概述:
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
构造方法:public Object(){...}
子类的构造方法默认访问父类的无参构造方法。
5.2 Object的hashCode()方法:
返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是:
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。【在同一个程序执行时期,同一个的对象的hashCode是不变的;相同程序在不同的执行时期,同一个对象的hashCode可能是不一致的。】
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
public class ObjectDemo01 { // public int hashCode() // 返回该对象的哈希码值,默认情况下,该方法会根据对象在内存中的存储地址来计算。 // 不同对象hashCode一般不同。但是同一个对象hashCode在某一个特定执行时期内是固定的。 public static void main(String[] args) { System.out.println(ObjectDemo01.class.hashCode()); // 1347167875 System.out.println(ObjectDemo01.class.hashCode()); System.out.println(ObjectDemo01.class.hashCode()); System.out.println(ObjectDemo01.class.hashCode()); } } |
5.3 Object的getClass()方法
public final Class<?> getClass()
返回此 Object 的运行时类。
泛型、反射。
5.4 Object的toString()方法
toString
public String toString()
返回该对象的字符串表示。通常, toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
该对象的字符串表示形式。
该toString()对我们来说没有太大意义,一般建议重写:
public class Person { private String name; private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Person [name="); builder.append(name); builder.append(", age="); builder.append(age); builder.append("]"); return builder.toString(); }
// @Override /* * public String toString() { return "Person [name=" + name + ",age=" + age * + "]"; } */ }
|
public class ObjectDemo03 { public static void main(String[] args) { Person person = new Person(); person.setName("隔壁老王"); person.setAge(20); System.out.println(person.toString()); } } |
5.5 Object的equals()方法:
特点:
指示其他某个对象是否与此对象“相等”;
默认情况下,比较的是对象的引用是否相同。
由于比较对象的引用没有意义,一般建议重写。
public class Person { private String name; private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public boolean equals(Object obj) { // 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。 if (this == obj) { return true; } // 对于任何非空引用值 x,x.equals(null) 都应返回 false。 if (obj == null) { return false; } // 如果类型不同,对象不可能相同 if (this.getClass() != obj.getClass()) { return false; }
// 类型相同,再来比较内容是否相同 Person ps = (Person) obj; /* * if (this.name.equals(ps.name) && this.age == ps.age) { return true; } */ return this.name.equals(ps.name) && this.age == ps.age; } }
|
public class ObjectDemo04 { public static void main(String[] args) { Person person1 = new Person(); person1.setAge(20); person1.setName("马云");
Person person2 = new Person(); person2.setName("马云"); person2.setAge(20);
if (person1.equals(person2)) { System.out.println("两个对象相等!"); } } } |
六、String类:
6.1 String类概述:
1、String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
2、字符串是常量;它们的值在创建之后不能更改。
6.2 String的构造方法:
String():
String(byte[] bytes):
String(String original):
public class StringDemo01 { public static void main(String[] args) { // 创建空字符串: String str1 = new String(); // 创建对象,分配内存
// 根据平台的字符集指定的数组,创建一个字符串 byte[] bytes = { 65, 66, 67, 68 }; String str2 = new String(bytes); System.out.println("str2:" + str2);
String str3 = new String("ABCD"); System.out.println("str3:" + str3); } }
|
6.3 面试题:
1、Sting s = new String(“abc”)这句话创建了几个对象?
1个或2个
2、程序题:
public class StringDemo02 { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); // true,比较的是引用,而s1和s2取的常量区中同一个字面量的地址。 System.out.println(s1.equals(s2)); // true
String str1 = new String("abc"); String str2 = new String("abc"); System.out.println(str1 == str2); // false,比较的是引用,在堆内存中不同对象的地址 } } |
3、程序题:
public class StringDemo03 { public static void main(String[] args) { String s1 = new String("abc"); // +——String的拼接符,在编译的时候,JVM会做特殊处理,结果会直接变成字面值常量"abc" String s2 = "a" + "b" + "c"; // 等价于String s2="abc"; System.out.println(s1 == s2); // false System.out.println(s1.equals(s2)); // true
String s3 = "abc"; System.out.println(s2 == s3); // true } } |
4、程序题:
6.4 String的判断功能:
1、public boolean equals(Object anObject)
将此字符串与指定的对象比较。当且仅当该参数不为null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。
注意:注意空指针异常问题:
public class StringDemo05 { public static void main(String[] args) { String s1 = "abc"; String s2 = null; if (s2.equals(s1)) { // Exception in thread "main" java.lang.NullPointerException 空指针异常 System.out.println("相等"); } else { System.out.println("不相等"); }
// 假设account是用户输入账号(有可能为null),dbAccount是数据库存储的账号(不为null) // if(account.equals(dbAccount)){ }写法错误 // if(dbAccount.equals(account)){ }写法正确 } } |
2、public boolean equalsIgnoreCase(String anotherString)
将此 String 与另一个 String 比较,不考虑大小写。如果两个字符串的长度相同,并且其中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。
3、public boolean contains(CharSequence s)
当且仅当此字符串包含指定的 char 值序列时,返回 true。
4、public String[] split(String regex)
根据给定 正则表达式的匹配拆分此字符串。
public class StringDemo06 { public static void main(String[] args) { String str = "Nice to meet you"; String[] words = str.split(" "); for (int i = 0; i < words.length; i++) { System.out.println(words[i]); } } } |
6.5 String的获取功能:
int length():返回此字符串的长度(字符个数)。
char charAt(int index):返回下标为index的字符。
int indexOf(int ch):返回字符串中第一次出现ch的索引。
int indexOf(int ch,int fromIndex):
int indexOf(String str):
int indexOf(String str,int fromIndex)
6.6 String的遍历:
public class StringDemo07 { public static void main(String[] args) { String str = "abcdefg"; for (int i = 0; i < str.length(); i++) { System.out.println(str.charAt(i)); } } } |
6.7 String类的转换功能:
String toUpperCase():小写转大写
String toLowerCase():大写转小写
char[] toCharArray():把字符串转换成字符数组
String concat(String str):把str字符串追加到当前字符串的结尾。
6.8 String的替换功能:
String replace(char oldChar,char newChar)
String replace(CharSequence target,CharSequence replacement)
String trim():返回字符串的副本,忽略前后的空白,对字符串中间的空格没有影响。
public class StringDemo08 { public static void main(String[] args) { String hello = " Nice to meet you.My name is Han MeiMei. "; System.out.println(hello); System.out.println(hello.trim()); } } |