Более простой способ - просто сгенерировать SVG в строку, создать HTML-элемент оболочки и вставить строку svg в элемент HTML с помощью $("#wrapperElement").html(svgString)
. Это прекрасно работает в Chrome и Firefox.
Когда вы расширяете класс, методы переопределяются, но поля скрыты. Динамическая диспетчеризация работает для методов, но не для полей. Почему язык разработан так, бог знает почему.
Dog.name
- скрывает Animal.name
, и это очень плохой шаблон для этого. Любая хорошая IDE предупредит вас о том, что вы это делаете.
Оба поля экземпляра существуют, и вы можете получить доступ к ним из Dog
как this.name
и super.name
.
В принципе, когда родительский класс имеет дочерний элемент, дочерний класс должен полностью выглядеть как его родитель, иначе «Как вы можете назвать их родителем и ребенком?» правильно? В любом случае, дочернему классу разрешено иметь поведение, отличное от его родителя. Это действительно разумно и естественно.
Но если вы хотите переопределить атрибут из дочернего класса, вы можете сделать это с помощью механизма конструктора
Пример кода
class Animal{
String name;
public Animal(){
name = "Animal";
}
public Animal(String name){
this.name = name;
}
public void print(){
System.out.println("I am an: "+name);
}
}
class Dog extends Animal{
Dog(){
super("Dog");
}
public void print(){
System.out.println("I am a: "+name);
}
}
Вы увидите, что имя атрибута "Dog"
в классе Dog
передается через конструктор, который здесь можно вызвать конструктор родительского класса через ключевое слово super
.
Результаты:
Animal object name: Animal
Dog1 object name: Dog
Dog2 object name: Dog
I am an: Animal
I am a: Dog
I am a: Dog
В Java мы используем метод set и get для доступа к полю. В вашем примере у нас есть класс Dog, расширяющий класс Animal.
Но если вы объявите его как Animal, если вы вызываете непосредственно поле Amimal dog1 = new Dog();
, вы создаете экземпляр Dog, но объявляетесь как Animal, поэтому, когда вы вызываете dog1.name
, он дает вам значение Animal.
Когда вы вызываете метод print
на animal
, JVM сначала ищет метод print
в объекте dog
. Если в объекте dog
не было print
, JVM будет искать суперкласс Dog
. Поскольку он находит метод print
в классе Dog
, он начинает его выполнять. Поле имени в классе Dog
скрывает поле имени, которое было унаследовано от класса Animal
. Его так же, как:
public class Test {
static String name = "xyz";
public static void main(String[] args) {
{
String name = "abc";
System.out.println(name); // abc is printed
}
System.out.println(name); // xyz is printed
}
}
Внутри блока есть локальная переменная name
. Таким образом, глобальная переменная name
скрыта. Но когда вы выходите из блока, появляется локальная переменная.
ПРИМЕЧАНИЕ:
Dog
класс должен выглядеть следующим образом:
class Dog extends Animal{
this.name = "Dog";
public void print(){
System.out.println("I am a: " + this.name);
}
}
Вы сделали плохой дизайн.
Поле Animal скрыто полем Dog, вы все равно можете получить доступ к полю Animal, указав его так же, как и вы.
Поведение, которое вы ожидаете, может быть достигнуто следующим образом:
public class Main{
public static void main(String args[]){
Animal animal = new Animal();
Animal dog1 = new Dog();
Dog dog2 = new Dog();
System.out.println("Animal object name: " + animal.name);
System.out.println("Dog1 object name: "+dog1.name);
System.out.println("Dog2 object name: " + dog2.name);
animal.print();
dog1.print();
dog2.print();
}
}
class Animal {
String name = "Animal";
public void print(){
System.out.println("I am an: "+name);
}
}
class Dog extends Animal{
public Dog() {
this.name = "Dog"
}
}
Нет, это не так. Переменные экземпляра - это свойства определенного класса и не подвержены непосредственно супер или подклассам и полиморфизму.
Вы можете получить доступ к в обоих полях, используя «super.name» и «this.name» в Dog, но если вы используете только «имя», то в Dog будет принимать участие. Если вы хотите другой, вам явно нужно вызвать супер. Обратите внимание, что я говорю о доступе к переменным в классе Dog .